我如何看待Git分支如何随时间变化(包括历史重写)?

时间:2016-08-06 15:30:57

标签: git version-control push rebase git-reflog

对于给定的回购和分支,有没有办法看到该分支如何随时间变化,包括历史重写?例如:

4月1日:承诺A - > B - > C - > d

4月2日,Max Heiber - git push -f:承诺A - > B - >的 C'

4月3日,其他人 - git merge feature提交A - > B - > C' - >的 d'

这就是为什么我要问:

我们正在将功能合并到dev分支中,但更改后来会从dev中消失。我们发现原因是我们的一位开发人员正在进行git push -f并在他的.gitconfig中使用了这个:

[push] default = matching

这具有强制推动所有分支的效果,包括陈旧版dev

花了一段时间才发现这种情况正在发生。在解决问题时,我们真正想要的是了解我们的历史如何以及为何发生变化。是否有可能获得这种分支的观点?

3 个答案:

答案 0 :(得分:2)

我不确定这是否适用于您的远程存储库,但它至少应该适用于您的本地存储库。

要查看dev分支上已完成的操作:

git reflog show dev

这应该显示过去30天内该分支的更改。

答案 1 :(得分:2)

Git并没有真正保存这些信息。如果你有reflogs,它会为reflog过期时间保存某些东西。默认情况下,这些时间分别为30天和90天,分别为无法访问和可访问的提交。 1 因此Gerhard Poul's answer将对您的本地dev起作用,并且因为reflog通常已启用对于远程跟踪分支机构,您还可以使用git reflog show origin/dev查看Git在git fetch / git pull操作期间记录的

到期时间通常从git gc开始,因此,如果git gc暂停一段时间,您可以获得额外的信息。

如果您的服务器上启用了reflog - 默认情况下它们未启用 - 您可以登录服务器并在那里运行git reflog show dev

在所有情况下,您可能需要添加--date=<format>(例如--date=iso)以将{@n}替换为@{date}

$ git reflog --date=iso master
11ae6ca master@{2016-06-17 13:32:00 -0700}: reset: moving to HEAD^
3d9eb53 master@{2016-06-17 13:31:44 -0700}: commit: Revert "fdmillion: repair example"
11ae6ca master@{2016-04-22 05:27:07 -0700}: commit (amend): add run-checks script
becf391 master@{2016-04-22 05:24:48 -0700}: commit: add run-checks script

这将为您提供每个参考更改的时间戳,这对于与“谁在什么时候做什么”相关联时非常有用。

1 这在技术上是无稽之谈。 :-)提交 - 好吧,所有Git对象,实际上是可访问的或无法访问的,但reflog条目使可以访问,所以这个特殊的速记可能令人费解。实际定义可从相应参考的当前值到达。也就是说,当git reflog expire到期时,它会查看:

  • 这是refs/heads/foo
  • 的reflog条目
  • 分支foo的名称是什么? (将此 H 称为头部)
  • 这个reflog条目名称的提交是什么? (将此 E 称为条目)
  • E H 的祖先? (见git merge-base --is-ancestor
  • 如果是,请使用gc.reflogExpiregc.<pattern>.reflogExpire
  • 如果不是,请使用gc.reflogExpireUnreachablegc.<pattern>.reflogExpireUnreachable

两个非模式名称分别默认为90.days.ago30.days.ago(默认情况下不设置模式值)。 refs/stash有一个特例,设置为never

答案 2 :(得分:1)

考虑到本地reflog可能会丢失,如果在强制推送后立即删除了本地仓库,我试图找到在远程仓库中强制更新的分支的历史记录。

创建远程仓库的新克隆并运行git gc,以便打包所有可到达的提交和相关对象,同时将无法访问的对象保留为松散对象,这可以在.git/objects中看到。但是我找不到任何git命令来列出这些无法访问的对象。 git rev-list似乎无法列出无法访问的对象。所以我尝试了一个dumm方法来列出它们,将第一个2字节文件夹名称和左侧38字节文件名一个接一个地加入一个完整的sha1中。然后逐个使用git cat-file -t <object>来查找所有提交对象。然后运行git show <commit-object>以查看所有内容。我认为在其中你可以在强制更新之前找到分支指向的提交。

当找到上一个提示提交时,可以恢复丢失的历史记录。