所以,听起来你想要两件事:
所以你想写一个脚本(命名git-something
并把它放在你的路径上,所以这是一个额外的 git 命令)来识别和处理这些提交。您需要一些触发器来让脚本识别本地提交。做到这一点的简单方法是在提交描述中放一个神奇的词——一个你永远不会在真实/共享提交中使用的词——以便脚本识别。(如果这对你来说听起来太不稳定,你也可以在提交的树中使用一个特殊的文件,比如.THIS_COMMIT_IS_LOCAL_ONLY
;我在示例中没有这样做,因为它有点难。)
您需要一个命令来从当前索引/工作目录进行本地提交;这很容易,它只是调用git commit $@ -m "__LOCAL_COMMIT_ONLY__"
(这是一个例子;关键是它会做一些事情来将正在创建的提交标记为仅限本地,然后推迟到 git 提交)。您还需要一个命令来临时弹出所有本地提交,执行一些其他 git 命令(拉、推、取、合并等),然后重新应用本地提交。您还将使用此命令来创建您打算共享的本地提交,以便它们始终出现在您的历史记录中仅本地提交的“下方”。
这是一个示例脚本,可将两者合二为一:
#!/bin/sh
if [[ $1 eq 'new' ]]; then
shift
exec git commit $@ -m "__LOCAL_COMMIT_ONLY__"
elif [[ $1 eq
OLD_HEAD=$(git rev-parse HEAD)
OLD_REAL_HEAD="$(git rev-list HEAD --grep=__LOCAL_COMMIT_ONLY__ | tail -n1)^"
git reset --soft $OLD_REAL_HEAD
git $@
git rebase --onto HEAD $OLD_REAL_HEAD $OLD_HEAD
现在,假设您调用脚本git-local
,使用git local new
从索引创建一个新的仅本地提交(或git local new -a
从工作目录中的修改文件创建),git local commit
(遗憾的是,名称不完美)创建一个新的“真实”提交,git local push
推、git local pull
拉等
这样做的主要缺点是它要求您记住大多数命令现在都以local
. 如果您忘记执行此操作,您会感到有些不知所措,但也不算太糟——快速git rebase -i
操作可以让您轻松地将本地提交移回顶部,然后您就可以重新开始运行了。最大的风险是您不小心使用git push
而不是git local push
将所有私人更改发送到上游,这会惹恼所有人。为此,您可能想要实际编写一个小包装脚本来调用而不是 git 本身(调用它~/bin/git
并确保~/bin
在您的路径上):
#!/bin/sh
if [[ $1 = 'push' ]]; then
if /usr/bin/git rev-list HEAD --grep=__LOCAL_COMMIT_ONLY__ | grep -q .; then
echo "Can't push with local changes still active!"
echo "Try using `git local push' instead."
exit 1
fi
fi
exec /usr/bin/git "$@"
您还可以pre-receive
在服务器上创建一个挂钩,自动拒绝__LOCAL_COMMIT_ONLY__
其消息中包含的任何提交。