Git - 获取他们创建的所有提交和 blob

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1314950/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 03:48:16  来源:igfitidea点击:

Git - get all commits and blobs they created

gitblobcommit

提问by tig

Is there a git command that can output for every commit:

是否有可以为每次提交输出的 git 命令:

  1. id
  2. subject
  3. blobs it created with they path and size (like git ls-tree -l -r <commit>but only for created blobs)
  1. ID
  2. 主题
  3. 它使用路径和大小git ls-tree -l -r <commit>创建的 blob (例如但仅适用于创建的 blob)

回答by tig

To get commits (all and output one line per commit):

获取提交(所有和每个提交输出一行):

git rev-list --all --pretty=oneline

Then split commits by space with limit of 2 and get every commit id and message

然后按空间拆分提交,限制为 2 并获取每个提交 ID 和消息

To get blobs created by commit (recurse to subdirs, show merge commits, detect renames and copies, don't show commit id on first line):

要获取由提交创建的 blob(递归到子目录,显示合并提交,检测重命名和副本,不要在第一行显示提交 ID):

git diff-tree -r -c -M -C --no-commit-id <commit-sha>

A bit of parsing of every line and excluding some of them — and we get list of new blobs and they path for commit

对每一行进行一些解析并排除其中的一些——我们得到新 blob 的列表和它们的提交路径

Last is to get blob sizes:

最后是获取 blob 大小:

git cat-file --batch-check < <list-of-blob-shas>

And another time a bit of parsing

还有一次有点解析

回答by maxschlepzig

Relying on git rev-listis not always enough because it

依靠git rev-list并不总是足够的,因为它

List[s] commits that are reachable by following the parent links from the given commit(s) [..]

列出 [s] 次提交,这些提交可通过跟随来自给定提交 [..] 的父链接访问

(git help rev-list)

( git help rev-list)

Thus it does not list commits that are on another branch and it does not list commits that are not reachable by any branch (perhaps they were created because of some rebaseand/or detached-head actions).

因此,它不会列出在另一个分支上的提交,也不会列出任何分支都无法访问的提交(也许它们是由于某些rebase和/或分离头操作而创建的)。

Similarly, git logjust follows the parent links from the current checked out commit. Again you don't see commits referenced by other branches or which are in a dangling state.

同样,git log只需遵循当前检出提交的父链接。同样,您看不到其他分支引用的提交或处于悬空状态的提交。

You can really get all commits with a command like this:

你真的可以使用这样的命令获得所有提交:

for i in `(find .git/objects  -type f |
             sed 's@^.*objects/\(..\)/\(.\+\)$@@' ;
           git verify-pack -v .git/objects/pack/*.idx  |
             grep commit |
             cut -f1 -d' '; ) | sort -u`
  do
  git log -1 --pretty=format:'%H %P %ai %s%n'  $i
done

To keep it simple, the loop body prints for each commit one line containing its hash, the parent hash(es), date and subject. Note, to iterate over allcommits you need to consider packed and not-yet packed objects.

为简单起见,循环体为每个提交打印一行,其中包含其散列、父散列、日期和主题。请注意,要迭代所有提交,您需要考虑打包和尚未打包的对象。

You can print the referenced blobs (and only created ones) by calling git diff-tree $i(and greping for capitial Ain the fifth column) from the loop body.

您可以通过从循环主体调用git diff-tree $i(并A在第五列中grep 获取资本)来打印引用的 blob(并且仅创建的blob )。

回答by Dustin

You can get everything but size out of the box. This one is pretty close:

除了尺寸外,您可以获得开箱即用的所有东西。这个非常接近:

git log --name-status

回答by Gavin Brock

One solution based on tig's answer:

基于tig的回答的一种解决方案:

#!/usr/bin/perl

foreach my $rev (`git rev-list --all --pretty=oneline`) {
  my $tot = 0;
  ($sha = $rev) =~ s/\s.*$//;
  foreach my $blob (`git diff-tree -r -c -M -C --no-commit-id $sha`) {
    $blob = (split /\s/, $blob)[3];
    next if $blob == "0000000000000000000000000000000000000000"; # Deleted
    my $size = `echo $blob | git cat-file --batch-check`;
    $size = (split /\s/, $size)[2];
    $tot += int($size);
  }
  print "$tot $rev" if $tot > 1000000; # Show only if > 1MiB
}

Maybe not the best code, but should get you most of the way.

也许不是最好的代码,但应该可以帮助您完成大部分工作。

回答by starsinmypockets

Another useful command when searching for

搜索时的另一个有用命令

git fsck --lost-found

will show dangling commits. I needed to use this to find a commit a i wiped with an ill-timed reset --hard

将显示悬空提交。我需要用它来找到一个用不合时宜的重置擦除的提交 ai --hard

But don't take my word for it:

但不要相信我的话:

https://www.kernel.org/pub/software/scm/git/docs/git-fsck.html

https://www.kernel.org/pub/software/scm/git/docs/git-fsck.html

回答by Toughy

You can also get a list of allcommits (including the dangling ones) with:

您还可以通过以下方式获取所有提交(包括悬空提交)的列表:

git log --walk-reflogs | grep -E -o '[0-9a-f]{40}'

git log --walk-reflogs | grep -E -o '[0-9a-f]{40}'

Include this line in the settings for a new view in gitk (in the last input field, the command to generate additional commits) and you will get a tree that also shows the 'forgotten history' of the project.

将此行包含在 gitk 中新视图的设置中(在最后一个输入字段中,生成额外提交的命令),您将获得一个树,其中还显示了项目的“被遗忘的历史”。