gitでコミット間を前後に移動するにはどうすればよいですか?


104

私はやっている git bisectそして問題のあるコミットに到達した後、私は今私が正しいものにいることを確認するために前進/後退することを試みています。

HEAD^は歴史を遡ることを知っていますが、次のように私を前進させる(将来の特定のコミットに向けて)別のショートカットがあります:

A - B - C(HEAD) - D - E - F

私のターゲットはFであり、CからDに移動したいと思っています。


注:これはGitの複製ではありません:コミット間を行き来する方法、私の質問は少し異なり、そこでは答えられません



git checkout -b new_branch HEAD~4stackoverflow.com/a/4940090/911945の
Anton Tarasenko

回答:


57

私は少し実験しました、そしてこれは前方にナビゲートするトリックをするようです(編集:マージコミットなしの線形履歴がある場合にのみうまく機能します):

git checkout $(git rev-list --topo-order HEAD..towards | tail -1)

どこ towardsコミットのSHA1またはタグです。

説明:

  • 内部のコマンド$()は、現在HEADとコミットの間のすべてのコミットを取得しtowards(を除くHEAD)、優先順位でソートしgit logます(デフォルトの場合と同様-奇妙なことにのデフォルトである年代順ではなくrev-list)、最後のコミットを取得します(tail)、つまり、行きたいもの。
  • これはサブシェルで評価され、git checkoutチェックアウトを実行するために渡されます。

.profile特定のコミットに向けてナビゲートするために、ファイル内のパラメーター期待エイリアスとしてアクセス可能な関数を定義できます。

# Go forward in Git commit hierarchy, towards particular commit 
# Usage:
#  gofwd v1.2.7
# Does nothing when the parameter is not specified.
gofwd() {
  git checkout $(git rev-list --topo-order HEAD.."$*" | tail -1)
}

# Go back in Git commit hierarchy
# Usage: 
#  goback
alias goback='git checkout HEAD~'

2
先に進むことは、履歴のまっすぐな部分ではうまく機能しますが、マージに遭遇するとループに入ります。
Kostas 2013年

ええ、私は実際にそれをマージでテストしていません。私は時間を
空け

2
正解です。現在のブランチを自動的に指定するように変更:stackoverflow.com/a/23172256/480608
Raine Revere

これは誤りです。git logrev-list--graphフラグを使用する場合を除いて、デフォルトでと同じように、コミットを発生順に表示します。
papiro

gitが複雑すぎるというかなり説得力のある証拠。通常、「元に戻す」または「やり直し」のように単純なものについては、ここには矛盾する答えのクレイジーなリストがあります。そして、私はリンクされた答えのいずれにも踏み込んでいません。FWIW、私は単純な線形のコミットのセットを使ってこのバージョンを試しましたが、ようやくあきらめました。
Snowcrash

49

ヘッドの状態を切り離すのではなく、明確にするために必要なのは、チェックアウトではなくリセットすることだけです。

git reset HEAD@{1}

5
またはgit reset "HEAD@{1}"、fishやpowershellなどの特定のシェルでgit reflogは、正しいコミットを見つけるのにも役立ちます。
スティーブクック

1
シェルが内容を解釈/展開することを明示的に要求しない限り、シェルコマンドでは常に一重引用符を使用してください。これは、シェルが特殊文字を解釈しないようにすることが目的であるこのような場合に特に重要です。そうすれば、文字列に問題のあるものが含まれているかどうかを知る必要はありません。
クリスページ

私は過去を振り返るためにそれをしました、そして私はgit reset HEAD私がいた場所に戻ってしなければなりませんでした...今、私は私のリポジトリがどのような状態にあるかわからず、すべてが怖いです。私は今どうすればいい?
theonlygusti

47

私はあなたができると信じています:

git reset HEAD@{1}

時間内に1つのコミットを進める。複数のコミットを進めるには、HEAD @ {2}、HEAD @ {3}などを使用します。


20

これは、私が前後にナビゲートするために使用しているものです。

次のコミットに移動

function n() {
    git log --reverse --pretty=%H master | grep -A 1 $(git rev-parse HEAD) | tail -n1 | xargs git checkout
}

前のコミットに移動

function p() {
    git checkout HEAD^1
}

ありがとう!今使っています!私のような他の初心者のためのメモ:HEADを再git checkout <current branch>アタッチするには、最新のコミットにアタッチします。git checkout -b <new-branch-name>現在のコミットから、新しいブランチでの変更を許可します。git rebase -iも動作します。また、ノードバージョンマネージャ「n」との競合を回避するために、n()関数に名前を付けましたnx()。エイリアスを確認してください!
Steven Choi

function(){...}は、Unix / Linux bashスクリプトファイルを作成するためのものです。私はWindowsから来たので、最初に理解するのは少し難しい
IcyBrk

動作していない=(。
Madeo

9

たとえば、Fが最新のコミットであるtrunk(ここに独自のブランチ名を挿入する)...として参照できますtrunk~0(または単にtrunk)、E as trunk~1、D astrunk~2などです。

コミットに名前を付ける他の方法については、reflogを確認してください。


1
〜前向きではなく戻る、トランク〜2はA
EmmanuelMess

はい。この回答はF、trunk というブランチがあり、そのブランチの履歴のどこに移動したいかを知っていることを前提としています。HEADに対して相対的に前に移動しようとするのではなく、トランクに対して相対的に遠くに移動しようとはしません。
役に立たない

@EmmanuelMess trunk~2A は元気ですか?
theonlygusti

@theonlygusti HEADから2度戻ります。
EmmanuelMess

あなたはまだ枝と仮定しているtrunkし、現在HEADされて同一のない私が述べてきた疑問に示すが、あるではない私は仮定して、そこを通ってハーフウェイはほとんどありませんよ何bisect
無駄

3

ツリーを下に移動しているので、逆方向にトラバースすることは簡単です。そして、常に1つの方法があります

  function git_down
        git checkout HEAD^
  end

前方にトラバースするときは、ツリーを上に移動するので、対象とするブランチを明示する必要があります。

  function git_up 
        git log --reverse --pretty=%H $argv | grep -A 1 (git rev-parse HEAD) | tail -n1 | xargs git checkout
  end

使用法:git downgit up <branch-name>


マージが含まれている場合、後退することも完全に一意ではありません。けれどもはHEAD^通常、合理的なデフォルトです。
kdb

2

先を見たい場合は、Gitに厳密なコマンドがないため、このトリックを実行できます。

git log --reverse COMMIT_HASH..

ログ履歴ハッシュのリスト:

A
B
C -> put this
D

コマンドを使用するgit log --reverse C..と、出力にBAが表示されます。


1

おそらく最も良い方法ではありませんgit logが、を使用git checkout [sha1 of D]してコミットのリストを表示し、を使用してDに移動できます。


6
私は彼がCでいた場合、その後、gitのログのみC、BおよびA.彼が表示されます、それを得ることはありません
Bilthon

わかりましたが、VonCのリンクに示されているようにトリッキーなgit-logを実行する必要があります
Bilthon

1

私はこれについてテストをしました。たとえば、masterブランチにいるとします。次に、次のようにします。

git checkout HEAD@{3}

したがって、頭が切り離され、他のコミットに移動するためにもう一度試すことができます。

git checkout HEAD@{4}

見終わったら、そのブランチにチェックアウトするだけで元の状態に戻ることができます。私の例では、マスターブランチ

git checkout master

元の状態に戻りたくなく、コミットの1つを頭に残してそこから続行したい場合は、そこから分岐する必要があります。たとえば、「git checkout HEAD @ {4}」の後に、

git checkout -b MyNewBranch


0

vsコードを使用している場合、Git履歴は、コミットを効率的に確認し、その内容をエディター自体で確認できる素晴らしいプラグインです。リンクをチェック


0
branchName=master; commitInOrder=1; git checkout $(git log --pretty=%H "${branchName}" | tac | head -n "${commitInOrder}" | tail -n 1)

どこ:

branchName ブランチ名に等しい

commitInOrder 選択したブランチの最初のコミットから順番にコミットする(つまり、1は最初のコミット、2はブランチの2番目のコミットなど)。

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