可以" git pull"自动存储和弹出挂起的更改?

时间:2015-05-13 07:58:14

标签: git git-pull git-stash

我知道如何解决这个问题:

user@host$ git pull
Updating 9386059..6e3ffde
error: Your local changes to the following files would be overwritten by merge:
    foo.bar
Please, commit your changes or stash them before you can merge.
Aborting

但是,有没有办法让git pull为我做stashpop舞会?

如果此命令具有不同的名称,则表示确定。

git stash; git pull; git stash pop创建shell别名是一种解决方案,但我会寻找更好的解决方案。

5 个答案:

答案 0 :(得分:147)

对于Git 2.6+(2015年9月28日发布)

唯一感兴趣的git config设置是:

rebase.autoStash
  

设置为true时,在操作开始前自动创建临时存储,并在操作结束后应用它   这意味着您可以在脏工作树上运行rebase。

     

但是,谨慎使用:成功重组后的最终存储应用程序可能会导致非平凡的冲突。默认为false。

将其与:

结合起来
pull.rebase
  

当为true时,rebase在获取的分支之上分支,而不是在运行“git pull”时合并默认远程的默认分支。

git config pull.rebase true
git config rebase.autoStash true

即使在肮脏的树中,这对于简单的git pull来说也足够了 在这种情况下不需要别名。

commit 53c76dcKevin Daudt (Ikke)(2015年7月4日) (由Junio C Hamano -- gitster --合并于commit e69b408,2015年8月17日)

  

pull:启用rebase.autostash时允许脏树

     

rebase在遇到脏工作树时学会了隐藏更改,   但git pull --rebase没有。

     

仅在rebase.autostash没有时验证工作树是否脏   启用。

注意:如果您想在不使用自动转发的情况下拉(即使设置了rebase.autoStash true),那么您就可以使用git 2.9(2016年6月):

 pull --rebase --no-autostash

请参阅commit 450dd1dcommit 1662297commit 44a59ffcommit 5c82bcdcommit 6ddc97ccommit eff960bcommit efa195d(2016年4月2日) ,commit f66398ecommit c48d73b(2016年3月21日)Mehul Jain (mehul2029) (由Junio C Hamano -- gitster --合并于commit 7c137bb,2016年4月13日)

Commit f66398e特别包括:

  

pull --rebase:添加--[no-]autostash标志

     

如果设置了rebase.autoStash配置变量,则无法进行   从命令行覆盖“git pull --rebase”。

     

教“git pull --rebase--[no-]autostash命令行标志   如果设置,则覆盖rebase.autoStash的当前值。作为“git rebase”   了解--[no-]autostash选项,这只是传递的问题   当调用“git rebase”时,基础“git pull --rebase”的选项。

警告:在Git 2.14(2017年第3季度)之前,当本地历史快速转发到上游时,“git pull --rebase --autostash”没有自动存储。

commit f15e7cfTyler Brazier (tylerbrazier)(2017年6月1日) (由Junio C Hamano -- gitster --合并于commit 35898ea,2017年6月5日)

  

pull:ff --rebase --autostash适用于脏仓库

     

当一个脏存储库中的git pull --rebase --autostash导致了一个   快进,没有任何东西自动减速,拉动失败   这是因为当我们可以快进时避免运行rebase的快捷方式,   但是在该代码路径上忽略了自动转发。

更新:Mariusz Pawelskiin the comments提出了一个有趣的问题:

  

所以当你做rebase(或autostash)时,每个人都在写pull --rebase

     

但是,当您使用合并进行正常拉动时,没有人会采取自动消除方法。
  那么没有自动切换?或者我错过了什么?我更喜欢git pull --rebase,但OP询问“标准”git pull

答案:

original thread 讨论此自动暂存功能,最初是为git pull(合并)和git pull --rebase实施的。

但是...... Junio C Hamano(Git maintainer)指出:

  

如果pull-merge会导致“烦恼”   根据定义,触发此主题的本地更改重叠   随着合并,这个内部的“藏匿流行音乐”将触及路径   合并触及,可能不会导致“掉线”而是离开   进一步的冲突有待解决。

     

我怀疑pull.autostash配置不是一个好的补充,因为它会鼓励一个糟糕的,引起痛苦的工作流程。
  在简单的情况下,它可能不会受到伤害,但是当局部变化很复杂时,它会比没有它更容易受到伤害,并且配置会激发选择的动机。

     

“pull-rebase”的等式与“rebase”有些不同   坚持要从干净的工作树开始,所以“下载并且   然后停止“烦恼感觉更大。我怀疑   放松这可能是解决实际问题的更有效方法。

因此,关于经典的拉式合并,最好是:

  

鼓励用户在运行“git pull之前考虑工作树中WIP的性质。

  它是一个太复杂的野兽,可能会干扰别人正在做的事情,或者   这是一个微不足道的变化,他可以藏匿并弹回它?

     

如果是前者,他会更好地做“checkout -b”,保持   工作直到局部变化形成一些更好的形状和   在进入原始分支之前“提交”。

     

如果是后者,他最好不要这样做:

     
      
  • git pull”,
  •   
  • 发现冲突后,运行      
        
    • git stash
    •   
    • git merge FETCH_HEAD
    •   
    • git stash pop
    •   
  •   

答案 1 :(得分:22)

为迎面而来的探险家节省几秒钟,这里有一个摘要(感谢@VonC):

git pull --rebase --autostash

答案 2 :(得分:14)

正如上面的评论所述,设置两个配置值目前不适用于git pull,因为autostash配置仅适用于实际的rebase。这些git命令可以执行您想要的操作:

git fetch
git rebase --autostash FETCH_HEAD

或将其设为别名:

git config alias.pullr '!git fetch; git rebase --autostash FETCH_HEAD'

然后做:

git pullr

当然,可以根据需要重命名此别名。

答案 3 :(得分:6)

使用Git 2.6+,您可以使用以下内容:

alias gup='git -c rebase.autoStash=true pull --rebase'

--rebase使git-pull使用rebase代替merge,因此--ff-only等设置/选项不会适用。

我默认使用别名来--ff-onlygit pull --ff-only),然后可以使用gup(来自上方),以防无法快进合并或有藏匿的变化。

答案 4 :(得分:1)

正如您已经提到的,这是实现它的方法。您可以在别名中使用它来保存您的输入和使用快捷方式,或者您可以在一行中使用它(也可以是别名)

git stash && git pull --rebase && git stash pop

它会做同样的事情,但只需一行(&&),你设置为别名,它甚至会更短。

以下几行将在您拉/推

之前显示传入/传出更改
git log ^master origin/master
git log master ^origin/master