我想列出只是特定分支的一部分的所有提交。

使用下面的代码,它列出了来自分支的所有提交,也包括来自父(master)的所有提交

git log mybranch

我发现的另一种选择是排除主可达的提交,并给我我想要的,但我想避免知道其他分支名称的需要。

git log mybranch --not master

我试图使用git for-each-ref,但它也列出了mybranch,所以实际上它排除了所有:

git log mybranch --not $(git for-each-ref --format '^%(refname:short)' refs/heads/)

更新:

我正在测试一个我不久前发现的新选项,直到现在看来,这可能是我一直在寻找的:

git log --walk-reflogs mybranch

更新(2013 - 02 - 13 t15:08):

——walk-reflogs选项很好,但我检查了reflogs的过期时间(默认90天,gc.reflogExpire)。

我想我找到了我一直在寻找的答案

git log mybranch --not $(git for-each-ref --format='%(refname)' refs/heads/ | grep -v "refs/heads/mybranch")

我只是从可用的分支列表中删除当前分支,并使用该列表从日志中排除。这样我只能得到只有mybranch才能到达的提交。


当前回答

选项1(似乎更快,但你可能会得到错误bash: /mingw64/bin/git:参数列表在git bash中太长(它在Linux中工作),这取决于你的项目有多少分支)

Git log <your_branch>——not $(Git branch -a | grep -v <your_branch> | grep -ve '->' | sed "s/\s//g")

选项2

git - rev-list <your_branch> | git -rev -stdin | sed -E 's/~[0-9]+//g;s / \ ^ [0 - 9] + / / g”| grep”< your_branch >”| awk - f”“{打印$ 1}’

其他回答

但是我想避免知道其他分支机构名称的需要。

我认为这是不可能的:Git中的一个分支总是基于另一个分支,或者至少是另一个提交,正如“Git diff并不显示足够”中解释的那样:

您需要一个日志参考点来显示正确的提交。

正如在“GIT -我从哪里分支?”:

分支只是指向DAG中特定提交的指针

所以即使git log master. mybranch是一个答案,它仍然会显示太多提交,如果mybranch是基于myotherbranch的,本身是基于master的。

为了找到这个引用(分支的起源),你只能解析提交并查看它们在哪个分支中,如下所示:

“Git:查找提交来自哪个分支”。 “我怎么能看到另一根树枝是从哪根树枝分叉的?”

这将输出当前分支上的提交。如果传递了任何参数,它只输出哈希值。

git_show_all_commits_only_on_this_branch

#!/bin/bash
function show_help()
{
  ME=$(basename $0)
  IT=$(cat <<EOF
  
  usage: $ME {NEWER_BRANCH} {OLDER_BRANCH} {VERBOSE}
  
  Compares 2 different branches, and lists the commits found only 
  in the first branch (newest branch). 

  e.g. 
  
  $ME         -> default. compares current branch to master
  $ME B1      -> compares branch B1 to master
  $ME B1 B2   -> compares branch B1 to B2
  $ME B1 B2 V -> compares branch B1 to B2, and displays commit messages
  
  )
  echo "$IT"
  exit
}

if [ "$1" == "help" ]
then
  show_help
fi

# Show commit msgs if any arg passed for arg 3
if [ "$3" ]
then
  OPT="-v"
fi

# get branch names
OLDER_BRANCH=${2:-"master"}
if [ -z "$1" ]
then
  NEWER_BRANCH=$(git rev-parse --abbrev-ref HEAD)
else
  NEWER_BRANCH=$1
fi

if [ "$NEWER_BRANCH" == "$OLDER_BRANCH" ]
then
  echo "  Please supply 2 different branches to compare!"
  show_help
fi

OUT=$(\git cherry $OPT $OLDER_BRANCH $NEWER_BRANCH)

if [ -z "$OUT" ]
then
  echo "No differences found. The branches $NEWER_BRANCH and $OLDER_BRANCH are in sync."
  exit;
fi

if [ "$OPT" == "-v" ]
then
  echo "$OUT"
else
  echo "$OUT" | awk '{print $2}'
fi

在这里,我根据Richard Hansen的回答(和Ben C的建议)给出了一个别名,但我对其进行了调整,以排除标签。别名应该相当健壮。

# For Git 1.22+
git config --global alias.only '!b=${1:-$(git branch --show-current)}; git log --oneline --graph "heads/$b" --not --exclude="$b" --branches --remotes #'
# For older Git:
git config --global alias.only '!b=${1:-$(git symbolic-ref -q --short HEAD)}; b=${b##heads/}; git log --oneline --graph "heads/$b" --not --exclude="$b" --branches --remotes #'

使用示例:

git only mybranch  # Show commits that are in mybranch ONLY
git only           # Show commits that are ONLY in current branch

注意,ONLY表示如果删除给定的分支(不包括标记的影响),提交将被丢失(在垃圾收集之后)。即使有一个名为mybranch的标记(多亏了前缀heads/),别名也应该工作。还要注意,根据ONLY的定义,如果提交是任何远程分支(包括上游分支)的一部分,则不会显示提交。

别名将单行历史记录显示为所选提交的图形。

  a --- b --- c --- master
   \           \
    \           d
     \           \
      e --- f --- g --- mybranch (HEAD)
       \
        h --- origin/other

对于上面的例子,git只会显示:

  * (mybranch,HEAD)
  * g
  |\
  | * d
  * f 

为了包含标签(但仍然不包括HEAD),别名变成(针对旧Git进行如上调整):

git config --global alias.only '!b=${1:-$(git branch --show-current)};  git log --oneline --graph --all --not --exclude="refs/heads/$b" --exclude=HEAD --all #'

或者包含所有标签的变体,包括HEAD(并默认删除当前分支,因为它不会输出任何东西):

git config --global alias.only '!git log --oneline --graph --all --not --exclude=\"refs/heads/$1\" --all #'

最后一个版本是唯一真正满足commit -that-are-lost-if-given-branch-is-deleted标准的版本,因为如果签出分支就不能删除分支,HEAD或任何其他标记指出的提交都不会丢失。然而,前两个变体更有用。

最后,别名不能用于远程分支(例如。Git只有origin/master)。别名必须修改,例如:

git config --global alias.remote-only '!git log --oneline --graph "$1" --not --exclude="$1" --remotes --branches #'

这是有效的:这完全符合你的要求:

for a in $(git rev-list anybranch..mybranch); do echo -n "$a "; git branch --contains $a | xargs; done

你可以使用严格的git rev-list——但如果你只关心某个分支上的提交,而不关心其他地方的提交,那么选择任何你认为自己来自的分支至少会限制实际的明显差异,而且你可以一眼看出哪些提交只属于该分支。

我需要在一行中为特定的分支导出日志。

所以我可能想出了一个更简单的解决方案。 当执行git log——pretty=oneline——graph时,我们可以看到当前分支中所有未完成的提交都是以|开头的行

所以一个简单的grep -v就可以了: Git log——pretty=oneline——graph | grep -v "^|"

当然,如果你需要其他信息,你可以改变pretty参数,只要你把它放在一行中。

您可能还想删除合并提交。 当消息以“Merge branch”开头时,再管道另一个grep -v,就完成了。

在我的具体情况下,最后的命令是: git log——pretty="%ad: %an, %s"——graph | grep -v "^|" | grep -v "合并分支"