强制推送当前分支

48

我经常将特性分支做变基操作,然后想强制推送到服务器。

git push --force origin feature-mongodb-support

有没有可以简化 git push --force origin <当前分支> 的快捷方式?


1
我总是设置config/tracking,以便git push仅推送到默认的远程跟踪分支。如果你能做到这一点,你可以使用git push -f吗?(只是好奇:如果你推送了一个错误的rebase,你在这个工作流程中有备份计划吗?我假设你是唯一在这些特性分支上工作的人?) - mpontillo
这个问题难道不是特别关于如何在常用的 git push -f origin <current branch name> 结构中摆脱当前分支名称吗?那么被接受的答案完全错过了重点,@Mike的评论应该被接受为答案。 - AndreKR
1
我认为最好的答案是将其设置为默认值:git config --global push.default current(来自这里)。 - orad
8个回答

33

您可以使用别名来缩短命令。像这样使用:

git config --global alias.fpush "push --force origin"

现在只需要输入以下命令即可推送您的分支:

git fpush feature-mongodb-support

或者您甚至可以将分支名称硬编码到命令中:

git alias fpush "push --force origin feature-mongodb-support"

并且只使用git fpush将你的宝贵工作推送到上游。

然而,非快进式更新是危险的,因为您基本上会覆盖掉在最后一次合并/变基到您的本地分支和强制推送之间在服务器上发生的所有历史记录。如果您经常需要执行此操作,则工作流程中肯定存在问题


我是唯一在一个特性分支上工作的人。我只想让这个特性分支能够快进合并到主分支,以便使我的工作更轻松。这样做有什么问题吗? - iblue
2
是的,这很危险。你将用一个命令覆盖你的分支。更好的方法是在功能完成后,交互式地将你的功能分支重新基于主分支。这样你的主分支仍然会有一个干净的历史记录,并且不会有所有这些覆盖的风险。 - Sergey K.
1
如果你遵循这个建议并在你的git别名中包含远程名称(通常是origin),你可能会遇到bash [tab]自动补全仍然尝试添加远程而不是直接跳转到提供分支名称的问题。为了解决这个问题,在source bash_completion之后在~/.profile中定义你自己的自定义替换函数:_git_fpush() { _git_branch; }(其中"fpush"匹配你的git别名的名称)。这将使bash将你的别名视为与“branch”命令相同。 - beporter
你说频繁使用 force push 是错误的。更新长期存在的分支有两种方法:合并和变基。当你选择变基方法时,你需要强制推送。如果要求在分支上拥有整洁、直接的历史记录,你还能用什么方法呢? - Ben Bucksch
@BenBucksch 假设你有10个开发人员在这个分支上工作,在你的变基和强制推送之间,其他人已经将他的负载推送到该分支。结果是你只是用你的强制推送覆盖了他们的工作。这种方式保持历史记录对于长期的私有分支来说是可以的,这里的私有指的是只有少数开发人员在该分支上的情况。对于数十个开发人员合作的分支,强制推送会造成严重破坏。 - Sergey K.
显示剩余6条评论

9
阅读了这些答案并阅读了与相关问题相关的答案(https://dev59.com/bmUp5IYBdhLWcg3wtZE0#18782415),我创建了此别名以基于当前分支名称强制推送到origin
fp = "!git push -f origin \"$(git rev-parse --abbrev-ref HEAD)\""

如果远程分支(我们要推送到的)与本地分支名称不同,那么这将如何工作? - user1021726
@user1021726,它不会。 - jlleblanc
这是回答整个问题的答案...但有一个限制,即本地分支和远程分支需要具有相同的名称。 - Damien
@jlleblanc 有没有办法让我排除主分支?即“仅当当前分支与主分支不同的情况下,将当前分支强行推送到远程”--原因是有时候我会在主分支上不小心执行"git fp",如果仓库中没有分支保护规则,那会很糟糕。 - James Wierzba

9
您可以通过设置 push.default 属性来更改默认行为:
git config --global push.default current

那么:
git push -f

该命令将强制推送到您当前的分支。

以下是来自http://schacon.github.io/git/git-config.html的复制/粘贴:

push.default

定义当没有在命令行上给定refspec、远程没有配置refspec,也没有通过命令行上给定的任何选项暗示refspec时,git push应采取的操作。 可能的值为:

  • nothing - 不推送任何东西。

  • matching - 推送所有匹配的分支。在双方都具有相同名称的所有分支都被视为匹配。这是默认设置。

  • upstream - 将当前分支推送到其上游分支。

  • tracking - 上游的废弃同义词。

  • current - 将当前分支推送到同名的分支。


工作得非常好,完全符合原帖的要求。谢谢! - Ben Bucksch

3

1

这应该能解决问题:

git alias fpush "push --force origin"

这将使您可以使用git fpush作为缩写的替代方式。

除非我弄错了,这会推送所有具有本地更改的分支,包括可能是主分支或完全不相关的分支,而不仅仅是当前分支。结合强制推送,这非常危险。 - Ben Bucksch

0
为了自动强制推送到“被跟踪”的分支(无论其名称和上游),我设计了这个别名:
fbrpush=!git push $(git rev-parse --abbrev-ref=loose --symbolic-full-name @{upstream} \
                    | sed 's:/: +:')

(为了易读性,此处换行)

(基于另一个SO答案)


0

当前分支名称也可以自动推断出来。

我使用一个小的 shell 脚本来强制推送到当前分支:

git branch | grep '*' | awk '{print $2}' | xargs -I % git push origin % -f

命令git branch会在当前分支上打上*符号,因此我们可以使用grep '*'获取相关行并解析以获取分支名称。

然后,快捷命令可以在.bashrc.zshrc中定义为别名:

alias gfp=/path/to/script

更新。

自Git 2.22版本以来(请参见此答案:stackoverflow.com/a/6245587/1326411),可以简化为:

alias git-fp='git branch --show-current | xargs -I % git push origin % --force-with-lease'

1
有更简单的方法:https://dev59.com/Hm025IYBdhLWcg3wCxZN#6245587 - Krakowski mudrac
非常感谢!看起来更加优雅 :) - Vladimir Vagaytsev

0

为了进一步阐述@jlleblanc的好答案,如果您想添加保护措施以防止强制推送到主分支(这可能非常难以撤消)

[alias]
    fp = "!branch=$(git branch --show-current); [[ -z $branch || $branch = 'master' ]] && echo 'Command cannot be used on master branch or when not on branch.' || git push -f origin \"$(git rev-parse --abbrev-ref HEAD)\""

它将做相同的事情,只是如果当前分支是主分支,它将跳过并打印警告。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接