如何在 git 中的提交之间向前和向后移动?

我正在做一个 git bisect,在到达有问题的提交之后,我现在试图前进/后退一步,以确保我在正确的提交中。

我知道 HEAD^可以让我回到过去,但是有没有另外一条捷径可以让我向前(在将来做一个具体的提交) ,就像这样:

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

我知道我的目标是 F,我想从 C移动到 D


注意: 这不是 Git: 如何在提交之间来回移动的副本,我的问题稍有不同,没有在那里回答

131576 次浏览

可能不是最好的方法,但是您可以使用 git log查看提交列表,然后使用 git checkout [sha1 of D]移动到 D。

假设 F 是 trunk上的最新提交(在这里插入您自己的分支名称) ... 您可以将其称为 trunk~0(或仅仅是 trunk) ,E 为 trunk~1,D 为 trunk~2等。

重新测试中查看更多命名提交的方法。

我已经做了一些实验,这似乎有助于向前导航(编辑: 只有当你有一个没有合并提交的线性历史时,它才能很好地工作) :

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

其中 towards是提交或标记的 SHA1。

说明:

  • $()中的命令意味着: 获取当前 HEADtowards提交之间的所有提交(不包括 HEAD) ,并按优先顺序对它们进行排序(就像在 git log中默认的那样——而不是 rev-list默认的按时间顺序) ,然后获取最后一个(tail) ,也就是我们想要进入的那个。
  • 这将在子 shell 中进行计算,并传递给 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~'

我相信你可以做到:

git reset HEAD@{1}

要及时向前提交一个提交。要向前提交多个提交,可以使用 HEAD@{2}、 HEAD@{3}等。

所有你需要清除,而不是分离的头状态是重置,而不是结帐。

git reset HEAD@{1}

作为一种解决方案,您可以返回到 HEAD

git checkout <branch>

然后移动到你想要的承诺,与

git checkout HEAD~<offset>

我刚做了个测试。 比如说,你在主分公司 然后:

git checkout HEAD@{3}

因此,头部被分离,然后你可以再次尝试进入任何其他提交:

git checkout HEAD@{4}

一旦您完成了四处查看,您可以通过检出到该分支返回到您的原始状态。在我的例子中: 主分支

git checkout master

如果您不想进入原始状态,并且希望保留一个提交作为您的头部,并从那里继续,那么您需要从那里开始扩展。 例如,在“ git checkout HEAD@{4}”之后,可以发出

git checkout -b MyNewBranch

我就是用这个来来回回导航的。

移动到下一个提交

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
}

向后遍历是微不足道的,因为您是沿着树向下移动的,而且总是有一条路可走

  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>

如果你使用的是 vs 代码,那么 Git 历史记录是一个非常棒的插件,你可以有效地查看提交,并在编辑器中检查它们的内容。 查看 < a href = “ https://markplacee.visalstudio.com/item? itemName = donjayamanne.githhistory”rel = “ nofollow noReferrer”> 链接

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

地点:

branchName等于分支名称

commitInOrder等于从所选分支中的第一次提交开始的提交(所以1是第一次提交,2是第二次提交,等等)

如果您想预见未来,您可以使用这个技巧,因为 Git 没有对它进行严格的命令。

git log --reverse COMMIT_HASH..

例子

日志历史散列列表:

A
B
C -> put this
D

使用命令 git log --reverse C..,在输出中您将看到 BA

对于 GUI 和 vscode 用户,我建议使用扩展 git 图形

enter image description here

我会用 git-refloggit-reset

这与运行 git-bisect的情况不同,但是假设您运行 git-reset来提交 C,并希望将其移回到提交 F。

在这一点上,git-reflog看起来是这样的:

$ git reflog show
4444444 (HEAD -> main) HEAD@{0}: reset: moving to 4444444
1111111 HEAD@{1}: commit: F
2222222 HEAD@{2}: commit: E
3333333 HEAD@{3}: commit: D
4444444 (HEAD -> main) HEAD@{4}: commit: C
5555555 HEAD@{5}: commit: B
6666666 HEAD@{6}: commit: A

然后,可以通过指定 HEAD 中的 SHA1散列或偏移数来运行 git-reset返回到任何提交。

在您的情况下,按如下方式运行 git-reset:

$ git reset 1111111

或者

$ git reset HEAD@{1}

向前进行一次提交的最短方法是:

git checkout @{1}

我稍后会加入这个注释,但是我构建了这行代码,它帮助我在任何 git tree上“前进”,我希望您也能发现它的有用之处。

注意,我不是一个 bash 魔术师,所以如果你发现什么可以改变,注释,我们可以使这行代码更好!

倒退:

git log --all --decorate --oneline | grep -A 1 $(git rev-parse --short HEAD) | awk '{print $1}' | tail -1 | xargs -I {} git checkout {}

继续前进:

git log --all --decorate --oneline | grep -B 1 $(git rev-parse --short HEAD) | awk '{print $1}' | head -1 | xargs -I {} git checkout {}

下面是一些解释:

git reflog # Here we get all the commits we need


grep -A 1 $(git rev-parse --short HEAD) # Here we grep for the short commit hash


awk '{print $1}' # Here we get just the hash


tail -1 # We will get at least 2 results, pick the last line, the first would be 0


xargs -I {} git checkout {} # Here we go "forward by 1"

希望这可以帮助任何人,希望得到同样的行为。我正在构建一个 CLI,它有一个命令,可以在提交树中“来回移动”,而不需要事先知道散列或日志。