回答:
git reset
はすべて移動に関するものHEAD
であり、一般的にはブランチ参照です。
質問:作業ツリーとインデックスはどうですか?
で使用する場合--soft
、移動しHEAD
、最も頻繁に分岐REFを更新し、そしてのみHEAD
。
これは以下とは異なりますcommit --amend
。
commit --amend
についてのみ)ちょうどこの組み合わせの例を見つけました:
すべてを1つにまとめます(タコ、2つ以上のブランチがマージされているため)コミットマージ。
Tomas "wereHamster" Carneckyは彼の"Subtree Octopus merge"記事で次のように説明しています:
- サブツリーマージ戦略は、あるプロジェクトを別のプロジェクトのサブディレクトリにマージし、その後サブプロジェクトを最新の状態に保つ場合に使用できます。gitサブモジュールの代替です。
- タコのマージ戦略は、3つ以上のブランチをマージするために使用できます。通常の戦略では2つのブランチしかマージできません。それ以上マージしようとすると、gitは自動的にタコ戦略にフォールバックします。
問題は、1つの戦略しか選択できないことです。しかし、リポジトリ全体がアトミックに新しいバージョンに更新されるクリーンな履歴を取得するために、2つを組み合わせたかったのです。
私はスーパー
projectA
プロジェクトを持っています、それをと呼びましょう、そしてサブプロジェクトをprojectB
サブディレクトリにマージしましたprojectA
。
(それがサブツリーのマージ部分です)
また、ローカルコミットもいくつか維持しています。
ProjectA
は定期的に更新され、projectB
数日または数週間ごとに新しいバージョンがあり、通常はの特定のバージョンに依存しprojectA
ます。私は両方のプロジェクトを更新することを決定したとき、私は単にから引っ張っていない
projectA
と、projectB
そのようプロジェクト全体の原子更新がどうあるべきかには2つのコミットを作成します。
代わりに、とローカルコミットを組み合わせた単一のマージコミットを作成しますprojectA
projectB
。
ここでトリッキーな部分は、これはタコのマージ(3つのヘッド)ですがprojectB
、サブツリー戦略とマージする必要があるということです。これが私がすることです:
# Merge projectA with the default strategy:
git merge projectA/master
# Merge projectB with the subtree strategy:
git merge -s subtree projectB/master
ここでは、著者が使用reset --hard
して、read-tree
最初の二つのマージが作業ツリーとインデックスに行っていたものを復元するために、それはどこでreset --soft
助けることができる:
私はこれら二つのマージやり直しにどのように取り組んできました、私の作業ツリーとインデックス、すなわちしています結構ですが、これらの2つのコミットを記録する必要はありませんか?
# Move the HEAD, and just the HEAD, two commits back!
git reset --soft HEAD@{2}
これで、Tomasのソリューションを再開できます。
# Pretend that we just did an octopus merge with three heads:
echo $(git rev-parse projectA/master) > .git/MERGE_HEAD
echo $(git rev-parse projectB/master) >> .git/MERGE_HEAD
# And finally do the commit:
git commit
したがって、毎回:
git reset --soft
答えです。
「エラー。これら3つのコミットは1つだけの可能性があります。」
そのため、最後の3つ(または何でも)のコミットを元に戻します(インデックスや作業ディレクトリには影響しません)。次に、すべての変更を1つとしてコミットします。
> git add -A; git commit -m "Start here."
> git add -A; git commit -m "One"
> git add -A; git commit -m "Two"
> git add -A' git commit -m "Three"
> git log --oneline --graph -4 --decorate
> * da883dc (HEAD, master) Three
> * 92d3eb7 Two
> * c6e82d3 One
> * e1e8042 Start here.
> git reset --soft HEAD~3
> git log --oneline --graph -1 --decorate
> * e1e8042 Start here.
これで、すべての変更が保存され、1つとしてコミットする準備が整いました。
これら2つのコマンドは本当に同じ(reset --soft
vs commit --amend
)ですか?
実用的にどちらか一方を使用する理由はありますか?
commit --amend
最後のコミットからファイルを追加/ rmするか、そのメッセージを変更します。 reset --soft <commit>
複数の順次コミットを組み合わせて新しいコミットにします。さらに重要なことに、reset --soft
コミットの修正以外に他の用途はありますか?
reset --soft
コミットの修正以外に他の用途はありますか-いいえ」の他の回答を参照してください
git reset
)は、(a)履歴を書き換えたい場合、(b)古いコミットを気にしない場合(インタラクティブなリベースの煩わしさを回避できるため)、および(c)変更へのコミットが複数ある(そうでない場合commit --amend
はより簡単です)。
私はそれを使って、最後のコミット以上のものを修正します。
コミットAでミスをしてからコミットBをしたとしましょう。今はBしか修正できないので、 git reset --soft HEAD^^
ため、Aを修正して再コミットし、次にBを再コミットします。
もちろん、大規模なコミットにはあまり便利ではありません…しかし、とにかく大規模なコミットを行うべきではありません;-)
git commit --fixup HEAD^^
git rebase --autosquash HEAD~X
うまくいきます。
git rebase --interactive HEAD^^
ここでは、コミットAとBの両方を編集することを選択します。これにより、AとBのコミットメッセージが保持されます。必要に応じて、これらも変更できます。
git reset A
、作成し、変更を加え、git commit --amend
、git cherry-pick <B-commit-hash>
。
別の潜在的な用途は、隠蔽の代替としてです(一部の人々はこれを好まない場合があります。たとえば、https://codingkilledthecat.wordpress.com/2012/04/27/git-stash-pop-considered-harmful/を参照してください)。)。
たとえば、私がブランチで作業していて、マスターで何かを緊急に修正する必要がある場合、私はただ行うことができます:
git commit -am "In progress."
次に、マスターをチェックアウトして修正を行います。終わったら、ブランチに戻って
git reset --soft HEAD~1
中断したところから作業を続けます。
--soft
変更をすぐにステージングすることに本当に関心がない限り、ここでは実際には不要です。私は今git reset HEAD~
これを行うときに使用します。私はいくつかの変更は、私は枝を切り替える必要があるとき上演、そして道というそれを維持したい場合、私はないgit commit -m "staged changes"
、そしてgit commit -am "unstaged changes"
、その後git reset HEAD~
に続いてgit reset --soft HEAD~
、完全に作業状態を復元します。正直に言うと、私はこれらの両方のことを私が知っている今ではそれほど多くはしていませんgit-worktree
:)
を使用git reset --soft
して、インデックスと作業ツリーにある変更の親として保持するバージョンを変更できます。これが役立つケースはまれです。ときどき、作業ツリーに加えた変更を別のブランチに属するように決定する場合があります。または、これをいくつかのコミットを1つに集約する簡単な方法として使用できます(スカッシュ/フォールドと同様)。
実用的な例については、VonCによるこの回答を参照してください。Gitで 最初の2つのコミットをスカッシュしますか?
git reset --soft anotherBranch
してコミットしますか?しかし、あなたは本当にckeckoutブランチを変更しないので、あなたは、にコミットします支店またはにanotherBranch?
考えられる使用法の1つは、別のマシンで作業を続けたい場合です。これは次のように機能します。
stashのような名前の新しいブランチをチェックアウトします。
git checkout -b <branchname>_stash
stashブランチを押し上げ、
git push -u origin <branchname>_stash
他のマシンに切り替えます。
あなたの隠し場所と既存のブランチの両方を引き下げ、
git checkout <branchname>_stash; git checkout <branchname>
これで、既存のブランチにいるはずです。stashブランチからの変更をマージし、
git merge <branchname>_stash
マージする前に、既存のブランチを1にソフトリセットします。
git reset --soft HEAD^
stashブランチを削除し、
git branch -d <branchname>_stash
また、stashブランチを元の場所から削除し、
git push origin :<branchname>_stash
変更を通常の方法で隠したかのように、変更を続けます。
将来的には、GitHubと共同で考えています。この「リモートスタッシュ」機能をより少ないステップで提供する必要があります。
実用的な使い方の1つは、すでにローカルリポジトリにコミットしている場合(つまり、git commit -m)、git reset --soft HEAD〜1を実行して、最後のコミットを元に戻すことができます。
また、参考までに、すでに変更をステージングしている場合(つまりgit addを使用している場合)は、git reset --mixed HEADを実行してステージングを逆にすることができますまでに、git reset
最後に、git reset --hardは、ローカルの変更を含むすべてを消去します。頭の後にある〜は、上から行くべきコミットの数を示します。
git reset --soft HEAD ~1
私が与えるfatal: Cannot do soft reset with paths.
私たちは、それは次のようになりますので、HEADの後にスペースを削除する必要があると思うgit reset --soft HEAD~1
「git reset --soft <sha1>
」を使用する大きな理由は、移動することですHEAD
は、ベアリポジトリです。
--mixed
またはを使用しようとした場合--hard
オプションしようとすると、存在しないツリーやインデックスを変更して作業しようとしているため、エラーが発生します。
注:これは、ベアリポジトリから直接行う必要があります。
注意:ベアリポジトリでリセットするブランチがアクティブなブランチであることを確認する必要があります。そうでない場合は、リポジトリに直接アクセスできるときに、ベアリポジトリのアクティブブランチを更新する方法に関するVonCの回答に従ってください。
SourceTreeは、必要なビットだけをステージングするための非常に便利なインターフェースを備えたgit GUIです。適切なリビジョンを修正するためにリモートで類似したものはありません。
したがってgit reset --soft HEAD~1
、よりもはるかに便利ですcommit --amend
、このシナリオ。コミットを元に戻し、すべての変更をステージング領域に戻し、SourceTreeを使用してステージングされたビットの微調整を再開できます。
実際にcommit --amend
は、2つのコマンドの方が冗長なコマンドであるように見えますが、gitはgitであり、わずかに異なる機能を実行する同様のコマンドを避けません。
私はこのスレッドの答えが本当に好きですが、私は git reset --soft
は少し異なっていますが、それでも非常に実用的なシナリオしています。
私は、開発用のIDEを使用します。これには、最後のコミット後の変更(ステージングおよびアンステージング)を表示するための優れたdiffツールがあります。今、私の仕事のほとんどは複数のコミットを伴います。たとえば、特定のタスクを完了するために5回コミットするとします。1〜5の増分コミットごとにIDEでdiffツールを使用して、最後のコミットからの変更を確認します。コミットする前に変更を確認するのに非常に役立つ方法だと思います。
しかし、私のタスクの最後に、すべての変更をまとめて(最初のコミットの前から)確認したい場合、プルリクエストを行う前にセルフコードレビューを行うと、前回のコミット(コミット後)からの変更のみが表示されます4)現在のタスクのすべてのコミットからの変更ではありません。
だから私はgit reset --soft HEAD~4
4つのコミットを戻すために使用します。これにより、すべての変更をまとめて確認できます。自分の変更に自信がある場合は、自信をgit reset HEAD@{1}
持ってリモートにプッシュできます。
git add --patch
、git commit
繰り返し実行して、一連のコミットシリーズを構築します。最初のコミットは、机の上のメモやメモの最初のドラフトのようなものであり、公開のためではなく、思考を整理するためにそこにあります。
git reset @{1}
、あなたの最初のドラフトシリーズを復元するには、代わりのために、出版シリーズを構築することができますgit add -p
し、git commit
。
もう1つの使用例は、プルリクエストで他のブランチを自分のものに置き換える場合です。たとえば、開発中の機能A、B、Cを持つソフトウェアがあるとします。
あなたは次のバージョンで開発していて、あなたは:
機能Bを削除
機能Dを追加
その過程で、機能Bに追加されたばかりのホットフィックスを開発します。
あなたは次の開発にマージすることができますが、それは時々面倒になる可能性がありますがgit reset --soft origin/develop
、変更を使用してコミットを作成し、ブランチが競合することなくマージ可能であり、変更を維持することもできます。
これはgit reset --soft
便利なコマンドです。私は個人的に、「WIP」のような「完了した作業」を持たないコミットをスカッシュするために多く使用するため、プルリクエストを開くと、すべてのコミットが理解できます。
git reset --soft
:stackoverflow.com/questions/6869705/...