如何查看 Git 分支随时间的变化情况(包括历史记录重写)?
How can I see how a Git branch changed over time (including history rewrites)?
对于给定的回购和分支,有没有办法查看该分支随时间的变化情况,包括历史重写?例如:
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
的陈旧版本。
花了一段时间才弄清楚这是怎么回事。在解决问题的同时,我们真正想要的是了解我们的历史如何以及为何发生变化。有没有可能得到这样的分支视图?
我不确定这是否适用于您的远程存储库,但它至少应该适用于您的本地存储库。
查看在开发分支上做了什么:
git reflog show dev
这应该会显示该分支在过去 30 天内的更改。
Git 并没有真正保存这些信息。如果您有 reflog,它会为 reflog 过期时间保存 something。这些时间默认为 30 天和 90 天,分别用于无法访问和可访问的提交。1 因此 将在您的本地 dev
上工作,并且因为 reflogs 是即使对于远程跟踪分支通常也启用,您还可以使用 git reflog show origin/dev
查看 您的 Git 在其 git fetch
/ git pull
操作。
过期通常是 运行 从 git gc
开始,所以如果 git gc
有一段时间没有 运行,你可以有相当多的额外信息。
如果您的服务器启用了 reflogs——默认情况下它们 未启用 ——您可以登录到您的服务器并在那里 运行 git reflog show dev
。
在所有情况下,您可能需要添加 --date=<format>
(例如 --date=iso
)以获得 {@<em>n</em>}
替换为 @{<em>date</em>}
:
$ 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
这将为您提供每次引用更改的时间戳,这对于与 "who did what when" 相关联很有用。
1这在技术上是无稽之谈。 :-) 提交——好吧,所有 Git 对象,真的——要么可达,要么不可达,但 reflog 条目 使 它们可达,所以 shorthand 的这一特定位可能令人费解。实际定义是从相应引用的当前值可达。也就是说,当 git reflog expire
使引用过期时,它会查看:
- 这是
refs/heads/foo
的 reflog 条目
- 分支
foo
名称是什么提交? (将此 H 称为头部)
- 这个 reflog 条目名称是什么提交? (将此称为 E 以供输入)
- 是EH的祖先吗? (参见
git merge-base --is-ancestor
)
- 如果是,使用
gc.reflogExpire
或gc.<pattern>.reflogExpire
- 如果没有,使用
gc.reflogExpireUnreachable
或gc.<pattern>.reflogExpireUnreachable
这两个非模式名称分别默认为90.days.ago
和30.days.ago
(默认不设置模式值)。 refs/stash
有一个特例,设置为 never
.
考虑到本地reflog可能会丢失,以防本地repo在强制推送后被删除,我试图在远程repo中找到被强制更新的分支的历史。
创建远程仓库的新克隆和 运行 git gc
以便打包所有可访问的提交和相关对象,而将不可访问的作为松散对象保留,这可以在.git/objects
。但是我就是找不到任何 git 命令来列出这些无法访问的对象。 git rev-list
似乎无法列出无法访问的对象。所以我尝试了一个dumm方法将它们全部列出来,将前2个字节的文件夹名称和左边的38个字节的文件名一个一个地拼接成一个完整的sha1。然后用git cat-file -t <object>
一个一个的找出所有的commit对象。然后 运行 git show <commit-object>
来查看所有内容。我认为在其中您可以找到分支在强制更新之前指向的提交。
当找到之前的提示提交时,丢失的历史记录可以取回。
对于给定的回购和分支,有没有办法查看该分支随时间的变化情况,包括历史重写?例如:
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
的陈旧版本。
花了一段时间才弄清楚这是怎么回事。在解决问题的同时,我们真正想要的是了解我们的历史如何以及为何发生变化。有没有可能得到这样的分支视图?
我不确定这是否适用于您的远程存储库,但它至少应该适用于您的本地存储库。
查看在开发分支上做了什么:
git reflog show dev
这应该会显示该分支在过去 30 天内的更改。
Git 并没有真正保存这些信息。如果您有 reflog,它会为 reflog 过期时间保存 something。这些时间默认为 30 天和 90 天,分别用于无法访问和可访问的提交。1 因此 dev
上工作,并且因为 reflogs 是即使对于远程跟踪分支通常也启用,您还可以使用 git reflog show origin/dev
查看 您的 Git 在其 git fetch
/ git pull
操作。
过期通常是 运行 从 git gc
开始,所以如果 git gc
有一段时间没有 运行,你可以有相当多的额外信息。
如果您的服务器启用了 reflogs——默认情况下它们 未启用 ——您可以登录到您的服务器并在那里 运行 git reflog show dev
。
在所有情况下,您可能需要添加 --date=<format>
(例如 --date=iso
)以获得 {@<em>n</em>}
替换为 @{<em>date</em>}
:
$ 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
这将为您提供每次引用更改的时间戳,这对于与 "who did what when" 相关联很有用。
1这在技术上是无稽之谈。 :-) 提交——好吧,所有 Git 对象,真的——要么可达,要么不可达,但 reflog 条目 使 它们可达,所以 shorthand 的这一特定位可能令人费解。实际定义是从相应引用的当前值可达。也就是说,当 git reflog expire
使引用过期时,它会查看:
- 这是
refs/heads/foo
的 reflog 条目
- 分支
foo
名称是什么提交? (将此 H 称为头部) - 这个 reflog 条目名称是什么提交? (将此称为 E 以供输入)
- 是EH的祖先吗? (参见
git merge-base --is-ancestor
) - 如果是,使用
gc.reflogExpire
或gc.<pattern>.reflogExpire
- 如果没有,使用
gc.reflogExpireUnreachable
或gc.<pattern>.reflogExpireUnreachable
这两个非模式名称分别默认为90.days.ago
和30.days.ago
(默认不设置模式值)。 refs/stash
有一个特例,设置为 never
.
考虑到本地reflog可能会丢失,以防本地repo在强制推送后被删除,我试图在远程repo中找到被强制更新的分支的历史。
创建远程仓库的新克隆和 运行 git gc
以便打包所有可访问的提交和相关对象,而将不可访问的作为松散对象保留,这可以在.git/objects
。但是我就是找不到任何 git 命令来列出这些无法访问的对象。 git rev-list
似乎无法列出无法访问的对象。所以我尝试了一个dumm方法将它们全部列出来,将前2个字节的文件夹名称和左边的38个字节的文件名一个一个地拼接成一个完整的sha1。然后用git cat-file -t <object>
一个一个的找出所有的commit对象。然后 运行 git show <commit-object>
来查看所有内容。我认为在其中您可以找到分支在强制更新之前指向的提交。
当找到之前的提示提交时,丢失的历史记录可以取回。