Git:マスターのステージングされていない/コミットされていない変更からブランチを作成する


991

コンテキスト:簡単な機能を追加するマスターに取り組んでいます。数分後、私はそれがそれほど単純ではなく、新しいブランチに取り組むほうがよかったことに気付きました。

これはいつも私に起こり、私は別のブランチに切り替えて、コミットされていない変更をすべてマスターブランチに残しておく方法を知りません。私git stash && git stash branch new_branchは単にそれを達成すると思いましたが、これは私が得るものです:

~/test $ git status
# On branch master
nothing to commit (working directory clean)

~/test $ echo "hello!" > testing 

~/test $ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   testing
#
no changes added to commit (use "git add" and/or "git commit -a")

~/test $ git stash
Saved working directory and index state WIP on master: 4402b8c testing
HEAD is now at 4402b8c testing

~/test $ git status
# On branch master
nothing to commit (working directory clean)

~/test $ git stash branch new_branch
Switched to a new branch 'new_branch'
# On branch new_branch
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   testing
#
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (db1b9a3391a82d86c9fdd26dab095ba9b820e35b)

~/test $ git s
# On branch new_branch
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   testing
#
no changes added to commit (use "git add" and/or "git commit -a")

~/test $ git checkout master
M   testing
Switched to branch 'master'

~/test $ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   testing
#
no changes added to commit (use "git add" and/or "git commit -a")

これを達成する方法があるかどうか知っていますか?


1
あなたの問題に対するより簡単な解決策がありますが、あなたが得る結果があなたが望むものと何が違うのかを特定できますか?
ゴーティエ2010

2
上記または下部の回答を実行すると、コミットされていない変更がマスターと新しいブランチの両方に反映されます。私はそれらを新しいブランチにのみ欲しいので、マスターをチェックアウトして、これらの変更を
浮かび上がら

1
私の編集した答えを見てください。クリーンマスターをチェックアウトする場合は、新しいブランチでローカルの変更をコミットする必要があります。ローカル変更は、現在のHEADとディスク上のファイルの違いのみです。ローカルファイルのこれらの変更はバージョン管理されていません。後で取得する場合は、gitにそれらをどこかに保存するように指示する必要があります。
Gauthier

回答:


1207

隠しておく必要はありません。

git checkout -b new_branch_name

ローカルの変更には影響しません。現在のHEADからブランチを作成し、そこにHEADを設定するだけです。だからそれがあなたの望んでいることだと思います。

---チェックアウトマスターの結果を説明するために編集---

checkout master変更を破棄しないので混乱していますか?

変更はローカルのみであるため、gitはそれらを簡単に失うことを望まない。ブランチを変更すると、gitはローカルの変更を上書きしません。あなたの結果checkout masterは:

M   testing

、つまり、作業ファイルがクリーンでないことを意味します。gitはHEADを変更しましたが、ローカルファイルを上書きしませんでした。そのため、あなたがオンになっているにもかかわらず、最後のステータスがローカルの変更を示していますmaster

ローカルの変更を本当に破棄したい場合は、でチェックアウトを強制する必要があります-f

git checkout master -f

あなたの変更は決してコミットされなかったので、あなたはそれらを失うでしょう。

ブランチに戻り、変更をコミットしてから、マスターをもう一度チェックアウトしてください。

git checkout new_branch
git commit -a -m"edited"
git checkout master
git status

あなたは得るべきであるMが、その後はないもはや後、最初のチェックアウト後にメッセージをcheckout master、そしてgit status何も変更されたファイルを示さないはずです。

---作業ディレクトリ(ローカルファイル)に関する混乱を解消するために編集します---

あなたの最初のコメントに答えて、ローカルな変更はただ...ローカルです。Gitはそれらを自動的に保存しないので、後で保存するように指示する必要があります。変更を加え、明示的にコミットまたはスタッシュしない場合、gitはそれらをバージョン管理しません。HEAD(checkout master)を変更した場合、ローカルの変更は保存されていないため上書きされません。


32
ここで混乱するのは、gitのマニュアルページにgit checkout「作業ツリーのファイルを更新して、インデックスまたは指定されたツリーのバージョンと一致させる」という記述です。これは、ファイルシステムの変更が後でなくなることを前提としています。それらを取り戻すチャンスなし。あなたがそうしないと言っても、これはまだ非常に悪い感じを残します。私はこれをまったく信用していません。ドキュメントが本当に悪いか、gitのデフォルトの動作が本当に危険です。この場合、変更を失いたくないことを検出するために、いくつかの「自動」ヒューリスティックを信頼する必要はありません。
Evi1M4chine 2013

16
ローカルの変更を上書きするコミットをチェックアウトする場合(現在のコミットとターゲットコミットの間の履歴がローカルで変更されたファイルに影響する場合)、gitは拒否します。checkoutローカルの変更と競合しない場合にのみ、チェックアウトは機能し、ローカルの変更はそのままになります。私は悪い気持ちを理解していますが、manページには「作業ツリーの変更されていないファイルを更新する」と書かれているはずです。一方、Gitはローカルの変更を失うことをあまりにも簡単にしません。git checkoutローカルでの変更のみを許可するか、競合がある場合は拒否します。
Gauthier

1
さて、ローカルの変更をそこに持ち込まずに、別のブランチにチェックアウトするにはどうすればよいですか?
アレックス

5
@アレックスgit checkout <other_branch> -f。警告なしにローカルの変更が失われます。
Gauthier 2014

2
@ Evi1M4chine最初のもの。ドキュメント本当に悪いです。
Qwertie

62

試してください:

git stash
git checkout -b new-branch
git stash apply

6
これは、 'git checkout -b new-branch'を単独で実行することとは異なりますか?
Adrian Mouat 2013

答えが最初に書かれた時ではなかったと思いますが、私は間違っているかもしれません。残念ながら、私の作業環境により、ここ数年はPERFORCEを使用しているため、現在はその正確さを証明できません。
Grant Limberg、2013

6
または、最後の2つのステップの代わりに:git stash branch new-branch
再タブを

1
git stashは不要になりました
kory 2016

すべてのものを入れたい既存のブランチがある場合、stashは私にとって理にかなっています。git checkout <既存のブランチ>; git stash apply;
Paolof76 2016年

24

あなたができる2つのこと:

git checkout -b sillyname
git commit -am "silly message"
git checkout - 

または

git stash -u
git branch sillyname stash@{0}

git checkout - <-ダッシュは前のブランチのショートカットです)

git stash -u<- -uステージングされていない変更も行うことを意味します)


7

(私と同じように)GitHub Windowsクライアントを使用していて、コミットされていない変更を加えて新しいブランチに移動したい場合は、GitHubクライアントを使用して「新しいブランチを作成」するだけです。新しく作成されたブランチに切り替わり、変更が保持されます。

ここに画像の説明を入力してください


新しいブランチを作成する前に変更を隠しておくため、変更は保持されません(Mac OSではバージョン223)
Fernando Gallego 2017

2

現在のブランチでコミットされていない現在の変更を新しいブランチに移動する場合は、次のコマンドを使用して新しいブランチを作成し、コミットされていない変更を自動的にコピーします。

git checkout -b branch_name

これにより、現在のブランチから新しいブランチが作成され(マスターであると想定)、コミットされていない変更がコピーされ、新しいブランチに切り替わります。

変更を新しいブランチにコミットします。

git commit -m "First commit"

新しいブランチが作成されるので、それをリモートにプッシュする前に、アップストリームを設定する必要があります。以下のコマンドを使用してアップストリームを設定し、リモートにプッシュします。

git push --set-upstream origin feature/feature/NEWBRANCH

このコマンドを押すと、新しいブランチがリモートに作成され、新しいローカルブランチがリモートにプッシュされます。

ここで、コミットされていない変更をマスターブランチから破棄する場合は、次のコマンドを使用します。

git checkout master -f

これにより、チェックアウト時にコミットされていないローカル変更が破棄されます。


この回答は承認された回答とどのように異なりますか?
閉店

受け入れられた回答と一部重複がありますが、これは簡単なステップバイステップガイドを提供し、新しいブランチをリモートでプッシュするために必要な操作も含まれています。シンプルで明確、そして便利です。
Kjartan

この答えは明確で、私に大いに役立ちました。
Vadim

0

最新のWindows用GitHubクライアントで、コミットされていない変更がある場合は、新しいブランチの作成を選択します。 この正確なシナリオを処理する方法を求めます。

ここに画像の説明を入力してください

ブランチを切り替えるだけでも同じことが言えます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.