そのブランチをチェックアウトせずにgitブランチでファイルをコミットすることは可能ですか?もしそうなら、どのように?
基本的に、ブランチを常に切り替えずにgithubpagesブランチにファイルを保存できるようにしたいです。何かご意見は?
更新:私が望むことを行うことはできません(ユースケースについては以下のコメントを参照してください)。私がやったことは、プログラムで現在のディレクトリをtmpディレクトリにクローンし、次にそのtmpディレクトリのブランチをチェックアウトして(作業ディレクトリには影響しません)、ファイルをtmpディレクトリのクローンにコミットすることです。完了したら、作業ディレクトリにプッシュバックして、tmpディレクトリを削除します。吸いますが、作業ディレクトリの現在の作業ブランチを変更せずにファイルを別のブランチにコミットする唯一の方法です。誰かがより良い解決策を持っているなら、下にそれを自由に追加してください。 「できない」より良ければ、受け入れます。
不可能です。
コミットする変更は、現在の作業コピーに関連しています。別のブランチにコミットする場合は、作業コピーから変更をコミットできますが、別のコピー状態に基づいて変更をコミットできることを意味します。
これは作業をバージョン管理する自然な方法ではありません。そのため、これを実行するには、さまざまな手順(変更のスタッシュ、ブランチのチェックアウト、スタッシュのポップ、コミット)を行う必要があります。
特定のユースケースに関しては、簡単な方法は、作業の2つのコピーを保持することです。1つはmaster
ブランチでチェックアウトし、もう1つはpages
ブランチでチェックアウトします。
pages
作業コピーで、master
コピーをリモートリポジトリとして追加します。
master
でページをコミットしますmaster
コピーのpages
からプルこれは、gitcommitを再実装することで実行できます。
これは、git hash-object
へのさまざまな呼び出しで実行できます。
しかし、これを達成するのは難しいです。
コミットをシミュレートする方法の詳細と完全な例については、 progit Chapter 9 をお読みください。
他の何人かが言ったように、それは文字通り可能ですが、非現実的です。
ただし、Git 2.5の時点で(2.6でいくつかの重要な修正があり、それ以降はマイナーな修正があります)、isgit worktree add
を使用してこれを行うための実用的な方法があります。
たとえば、ブランチmain
とdoc
を「同時に」、またはブランチdevelop
とtest
を「同時に」作業したいとします。同時に」が、問題の2つのブランチには意図的に異なるものが含まれています。 (たとえば、doc
ブランチには、コードの外部または横に存在するドキュメントがあります。または、test
ブランチには、コードに対して実行されるが配布されないテストがあるか、またはdevelop
側などで、テストが意図的にスキップされた障害があります。)
ただの代わりに:
git clone -b develop <source> theclone
続いて、theclone
で作業し、2つのブランチ間を絶えず切り替えて、次のようにします。
git clone -b develop <source> theclone
しかしその後:
cd theclone
git worktree add ../ct test # check out branch test in ../ct
あるいは単に:
git worktree add ../test # check out branch test in ../test
これで、theclone
で開発しながら、../test
でテストを実行できます。通常の方法で、あるブランチから別のブランチに変更をマージおよび/またはリベースできます。基になるリポジトリはすでに共有されているため、git Push
またはgit fetch
は必要ありません。単純に両方ブランチをチェックアウトして、トップレベルからtheclone
とtest
という名前の2つの別々のワークツリーにします。
現在のインデックスにHEAD
と異なるものがない限り、このようなことができます。 (インデックスを保持したい場合は、これらのコマンドの実行中、一時ファイルを指すようにGIT_INDEX_FILE
環境変数を一時的にエクスポートできます。)
# Reset index and HEAD to otherbranch
git reset otherbranch
# make commit for otherbranch
git add file-to-commit
git commit "edited file"
# force recreate otherbranch to here
git branch -f otherbranch
# Go back to where we were before
# (two commits ago, the reset and the commit)
git reset HEAD@{2}
実際にotherbranch
をチェックアウトしたことはなく、作業ツリーファイルも変更されていません。
私はそれが不可能であることに同意することはできません。 git stash Push
、git stash pop
、git checkout
、git checkout
、git add
、およびgit commit
を混合することにより、これが可能になります。
問題の理解方法:
ブランチマスターを使用していて、ファイルpatched.txt
にいくつかの変更を加え、このファイルを他のブランチにコミットしたいと考えています。
やりたいことは:
file.txt
patched
(およびこのファイルのみ)を新しいブランチに追加しますfile.txt
を変更する前にリポジトリの状態に戻りますこれは次のコマンドを実行することで実現できます:
destBranch=patch
thisBranch=master
FileToPutToOtherBranch="file1.txt file2.txt 'file with space in name.txt'"
message="patched files $FileToPutToOtherBranch"
#assumption: we are on master to which modifications to file.txt should not belong
git stash &&\ #at this point we have clean repository to $thisBranch
git checkout -b $destBranch &&\
git checkout stash@{0} -- $FileToPutToOtherBranch && #if there are many files, repeat this step #create branch if does not exist (param -b)
git add $FileToPutToOtherBranch &&\ # at this point this is equal to git add . --update
git commit -m "$message" &&\
git checkout $thisBranch &&\
git stash apply &&\ # or pop if want to loose backup
git checkout $thisBranch -- $FileToPutToOtherBranch # get unpatched files from previous branch
「&&」を使用して終了する理由は、誰かがこのスニペットをコピーしてターミナルに貼り付ける場合、1つのエラーが発生しても、次のコマンドが実行されるため、適切ではありません。\は、シェルにそのコマンドを通知するためのものです。次の行に続きます。
この動作を証明するために、このスニペットのテスト環境を提供します
mkdir -p /tmp/gitcommitToAnyBranch && cd /tmp/gitcommitToAnyBranch &&\
git init
echo 'this is master file' > file1.txt
echo 'this is file we do not want to have modified in patch branch because it does not patches any feature' > docs.txt
git add file1.txt && git commit -m "initial commit"
echo 'now this file gets patched' > file1.txt
git status
さて、パラメータを使ってスクリプトを実行すると
destBranch=patch
thisBranch=`git rev-parse --abbrev-ref HEAD`
FileToPutToOtherBranch="file1.txt"
message="patched file $FileToPutToOtherBranch"
パッチブランチでのみfile1.txt
が変更されます。詳細についてはgitk --all
を参照してください。
私はまさにこれを行う小さなツールを作りました: https://github.com/qwertzguy/git-quick
他のブランチを完全にチェックアウトせずに(編集したいファイルだけ)、別のブランチから特定のファイルを編集してコミットすることができます。作業コピーやステージング領域に影響を与えることなく、これらすべてを実行できます。
舞台裏では、gitワークツリーとスパースチェックアウトの組み合わせを使用しています。ソースはかなり小さいので、読み通すことができます。
間違ったブランチで誤って変更した場合は、次の簡単な手順を実行してください。
この後はすべてうまくいくはずです。変更を選択的にマージ、リセット、およびクリーンアップすることもできます。
これが私のやり方です:
私が酸的にコミットした場合は、1つのコミットをロールバックします。
git reset --soft 'HEAD^'
追加したいファイルを追加します
git add .
新しい一時ブランチを作成します。
git checkout -b oops-temp
変更をコミットします。
git commit -m "message about this commit"
チェックアウトする予定のブランチをチェックアウトします。
git checkout realbranch
古いブランチをマージします。
git merge oops-temp
古いブランチを削除します。
git branch -D oops-temp
いいえ、できません。ただし、ファイルをハードコピーして実行していることは、コミットを使用してgit stash
によって実装されます。 stash
は、保存される変更のスタックとして機能します"ブランチスペースの外側のどこか"、したがって、ブランチ間で変更を移動するために使用できます。
<file>
で変更を加えます<file>
<branch you want to commit>
<commit message>
"これを絶えず行うと、おそらくこれらの単純なコマンドを書き留めることができます。