2

概括

在当前分支中查找也包含在任何其他分支中的最新提交的最快方法是什么?

奖励:该技术能否允许上述问题中的“任何其他分支”成为“任何其他远程分支”或“任何其他本地分支”?


背景

我喜欢使用git rebase -i. 我的主要用例是在推送到远程之前重新组织提交。因此,我经常这样做git rebase -i origin/master。因此,我为该操作设置了一个别名,称为git rewrite.

问题是我并不总是想针对origin/master. 例如,我可能正在一个分支上工作,而是想要git rewritegit rebase -i origin/branch. 或者我可能正在当地的分支机构工作并git rewrite想做git rebase -i localbranch.

所以实际上,我正在尝试让我的git rewrite脚本执行以下操作:“从包含在任何其他分支中的最后一次提交中进行交互式变基”。我想出的是:(仅适用于查找远程分支)

#!/bin/bash

# Do a git rebase -i from the most recent common point between the
# current branch and any other remote branch.

# We go backwards in the branch's history and for each commit check if
# that commit is present in one of the remote branches. As soon as we
# find one that is, we stop and rebase on that.

commit=$(git rev-parse HEAD)
while [ true ]; do
   branch=$(git branch -r --contains $commit)
   if [ -n "$branch" ]; then
      # This commit exists in another remote branch!
      break
   fi
   # OK, let's try the previous commit
   commit=$(git log --pretty=%P -n 1 $commit)
   # Stupid heuristic, take only first commit if multiple parents
   commit=${commit%% *}
done

git rebase -i $commit

这种方法的问题是它很。这也有点不准确,因为当提交有多个父级时,它只跟随一个父级。

有谁知道这样做更好/更快/更清洁的方式?

4

2 回答 2

3

重写脚本可能如下所示(bash):

#!/bin/bash
count=0
for rev in $(git rev-list HEAD); do
    num=$(git branch --all --contains ${rev} | wc | awk '{print $1}')
    [ ${num} -eq 1 ] || break
    count=$(( count + 1 ))
done
if [ ${count} -gt 0 ]; then
    git rebase -i HEAD~${count}
fi

我经常做的是(从上游点变基):

git rebase -i @{u}

然而,该@{u}技术并没有捕捉到其他分支。

于 2014-02-16T21:12:59.263 回答
1

我会去

git for-each-ref refs/heads --format='git merge-base %(refname) yourbranch' \
| sh >merge-bases
git log --first-parent --format='%H %s' \
| grep -f merge-bases -

refs/heads是“任何本地分支”版本,添加或替换refs/remotes远程分支。

进程替换显然不会与 Windows 上的管道混合,在 Linux 上,您可以通过这种方式避免临时文件。

(编辑:aaannd grep 也有后级,把它搞砸了)

于 2014-02-16T20:33:53.393 回答