git rebase -i shortcut - 找到最好的rebase提交

时间:2014-02-16 18:01:38

标签: git version-control git-rebase git-interactive-rebase

摘要

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

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


背景

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

问题在于我并不总是想要反对origin/master。例如,我可能正在处理分支,而是希望git rewrite执行git rebase -i origin/branch。或者我可能在当地分支机构工作,希望git rewrite能够git rebase -i localbranch

所以实际上,我试图让我的git rewrite脚本做类似的事情:“从任何其他分支中包含的最后一次提交做一个交互式rebase”。我想出的是:(仅适用于寻找远程分支)

#!/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

此方法存在的问题是。它也有点不准确,因为当一个提交有多个父母时它只跟随一个父母。

有没有人知道更好/更快/更清洁的方式呢?

2 个答案:

答案 0 :(得分:2)

重写脚本可能如下所示(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}技术不会捕获其他分支。

答案 1 :(得分: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上你可以避免使用临时文件。

(编辑:aaaannd grep那里也有反面,愚蠢的下来)