我正在使用git,我希望能够创建一个未与远程存储库同步的提交.这样的提交必须"浮动"在本地存储库中的所有其他提交之上,以避免影响历史记录.我可以使用这样的提交来存储特定于本地的更改(配置更改,调试标志,本地解决方法等).
目前,当我提交将提交重新排序回顶部时,我手动重新绑定,并且我推动使用HEAD^以避免推送本地更改.我也考虑过把这些变化放在藏匿处,但那不太方便,因为它排除了正常使用藏匿处.另一种方法是简单地将所有这些本地更改保留为未分级,并在git add -p每次我想要提交时使用.然而,随着大量琐碎的局部变化,这变得麻烦.
这是我当前工作流程的一个示例:
我的存储库最初看起来像
A---B---C---F master
Run Code Online (Sandbox Code Playgroud)
其中"F"是我的浮动提交.
我做了一个提交:
A---B---C---F---D master
Run Code Online (Sandbox Code Playgroud)
然后git rebase -i HEAD~2重新排序:
A---B---C---D---F master
Run Code Online (Sandbox Code Playgroud)
然后git push remote HEAD~1...推送除了本地F提交之外的所有内容.
更改F包含对现有版本化文件的更改,并且可能包含任意数量的更改.(如果我可以让多个提交"浮动",那就更好了,因为我可以将我的本地更改分开).
Jon*_*mer 16
所以,听起来你想要两件事:
一些提交应该保密(例如在本地分支上),并且当你拉动时从不推送或合并; 它们应该保留在"共享提交之后".
这对你来说应该是最透明的; 你想在master上工作,并自动维护本地分支.您只需确定哪些提交应该是本地的,并且与远程存储库交互的命令将忽略这些提交.
因此,您希望编写一个脚本(git-something将其命名并将其放在路径上,这是一个额外的git命令)来识别和处理这些提交.您需要一些触发器来让脚本识别本地提交.执行此操作的简单方法是在提交描述中添加一个神奇的单词 - 您将永远不会在真实/共享提交中使用 - 以供脚本识别.(如果这对你来说太过分散,你也可以在提交树中使用一个特殊的文件,比如.THIS_COMMIT_IS_LOCAL_ONLY;我在示例中没有这样做,因为它有点困难.)
您需要一个命令来从当前索引/ workdir进行本地提交; 这很容易,它只是调用git commit $@ -m "__LOCAL_COMMIT_ONLY__"(这是一个例子;关键是它做了什么来标记提交被创建为仅本地,然后遵循git提交).您还需要一个命令来暂时弹出所有本地提交,执行其他一些git命令(pull,push,fetch,merge等),然后重新应用本地提交.您还将使用此命令创建您打算共享的本地提交,以便它们始终显示在历史记录中仅限本地提交的"下方".
这是一个示例脚本,可以同时为您提供:
#!/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
Run Code Online (Sandbox Code Playgroud)
现在,假设您调用脚本git-local,使用git local new从索引创建一个新的仅本地提交(或git local new -a从workdir中的已修改文件创建),git local commit(名称不完美,遗憾地)创建一个新的"真正"提交,git local push推,git local pull拉等
这个的主要缺点是它要求你记住大多数命令现在都带有前缀local.如果你忘记这样做一次,你会有点h,但不会太糟糕 - 快速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 "$@"
Run Code Online (Sandbox Code Playgroud)
您还可以pre-receive在服务器上创建一个自动拒绝__LOCAL_COMMIT_ONLY__其消息中包含的任何提交的挂钩.
Bey*_*mor 11
在以前的工作中,每个人都有自己的本地settings分支,我们在其上提交了我们的个人设置.这个分支是基于master; 任何主题分支都是分支的settings.当主题准备好集成时,我们将它们重新定位到master.这似乎是@koljaTM的建议.
A---B---C master
\
F settings
\
D topic
rebase --onto master settings topic
A---B---C master
|\
| F settings
\
D topic
Run Code Online (Sandbox Code Playgroud)
当新的变化打master,我们会重订settings的master,那么重订我们的工作就关闭任何主题settings.
不可否认,这不是一步一步"永远留下这个浮动"的解决方案,但它足够干净和简单.
Luk*_*uke 10
您可以使用可以从Git生成的补丁文件.
# git diff > local.patch
Run Code Online (Sandbox Code Playgroud)
如果要提交,请反向修补:
# git apply -R local.patch
Run Code Online (Sandbox Code Playgroud)
提交后,恢复补丁:
# git apply local.patch
Run Code Online (Sandbox Code Playgroud)
在创建补丁文件之前,您只需确保工作树上只有本地更改.创建补丁文件后,您可以将其添加到.gitignore您不提交的位置.