“git pull”可以自动隐藏和弹出待处理的更改吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30208928/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can "git pull" automatically stash and pop pending changes?
提问by guettli
I know how to solve this:
我知道如何解决这个问题:
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
But isn't there a way to let git pull
do the stash
and pop
dance for me?
但是,是不是有办法让git pull
做stash
和pop
舞蹈给我吗?
If this command has a different name, it's ok.
如果这个命令有一个不同的名字,那没关系。
Creating a shell alias for git stash; git pull; git stash pop
is a solution, but I search for a better solution.
为 for 创建 shell 别名git stash; git pull; git stash pop
是一种解决方案,但我正在寻找更好的解决方案。
回答by VonC
For Git 2.6+ (released 28 Sept 2015)
对于 Git 2.6+(2015 年 9 月 28 日发布)
The onlygit config
setting which would be of interest is:
这 只要git config
感兴趣的设置是:
rebase.autoStash
(with Git 2.27, Q2 2020, you now also have merge.autostash
, see below)
(在 2020 年第 2 季度的 Git 2.27 中,您现在还拥有merge.autostash
,见下文)
When set to true, automatically create a temporary stash before the operation begins, and apply it after the operation ends.
This means that you can run rebase on a dirty worktree.However, use with care: the final stash application after a successful rebase might result in non-trivial conflicts. Defaults to false.
当设置为 true 时,在操作开始前自动创建一个临时存储,并在操作结束后应用它。
这意味着您可以在脏工作树上运行 rebase。但是,请谨慎使用:成功 rebase 后的最终存储应用程序可能会导致重大冲突。默认为假。
combine that with:
结合:
pull.rebase
When true, rebase branches on top of the fetched branch, instead of merging the default branch from the default remote when "git pull" is run.
如果为 true,则在获取的分支之上重新设置分支,而不是在运行“git pull”时从默认远程合并默认分支。
git config pull.rebase true
git config rebase.autoStash true
That would be enough for a simple git pull
to work even in a dirty tree.
No alias needed in that case.
git pull
即使在肮脏的树上,这也足以让简单的工作。
在这种情况下不需要别名。
See commit 53c76dc(04 Jul 2015) by Kevin Daudt (Ikke
).
(Merged by Junio C Hamano -- gitster
--in commit e69b408, 17 Aug 2015)
请参阅Kevin Daudt ( ) 的commit 53c76dc(2015 年 7 月 4 日)。(由Junio C Hamano合并-- --在提交 e69b408 中,2015 年 8 月 17 日)Ikke
gitster
pull
: allow dirty tree whenrebase.autostash
enabledrebase learned to stash changes when it encounters a dirty work tree, but
git pull --rebase
does not.Only verify if the working tree is dirty when
rebase.autostash
is not enabled.
pull
:rebase.autostash
启用时允许脏树当遇到脏工作树时,rebase 学会了隐藏更改,但
git pull --rebase
没有。仅在
rebase.autostash
未启用时验证工作树是否脏。
Note: if you want to pull withoutautostash (even though rebase.autoStash true
is set), you have since git 2.9 (June 2016):
注意:如果你想在没有autostash 的情况下拉取(即使rebase.autoStash true
设置),你从 git 2.9(2016 年 6 月)开始:
pull --rebase --no-autostash
See commit 450dd1d, commit 1662297, commit 44a59ff, commit 5c82bcd, commit 6ddc97c, commit eff960b, commit efa195d(02 Apr 2016), and commit f66398e, commit c48d73b(21 Mar 2016) by Mehul Jain (mehul2029
).
(Merged by Junio C Hamano -- gitster
--in commit 7c137bb, 13 Apr 2016)
见提交450dd1d,提交1662297,提交44a59ff,提交5c82bcd,提交6ddc97c,提交eff960b,提交efa195d(2016年4月2日),以及提交f66398e,提交c48d73b(2016年3月21日)由MEHUL耆那(mehul2029
)。
(由Junio C gitster
Hamano合并-- --在commit 7c137bb,2016 年 4 月 13 日)
Commit f66398ein particular includes:
Commit f66398e特别包括:
pull --rebase
: add--[no-]autostash
flagIf
rebase.autoStash
configuration variable is set, there is no way to override it for "git pull --rebase
" from the command line.Teach "
git pull --rebase
" the--[no-]autostash
command line flag which overrides the current value ofrebase.autoStash
, if set. As "git rebase
" understands the--[no-]autostash
option, it's just a matter of passing the option to underlying "git rebase
" when "git pull --rebase
" is called.
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
。
Warning: before Git 2.14 (Q3 2017), "git pull --rebase --autostash
" didn't auto-stash when the local history fast-forwards to the upstream.
警告:在 Git 2.14(2017 年第三季度)之前,git pull --rebase --autostash
当本地历史快进到上游时," " 不会自动存储。
See commit f15e7cf(01 Jun 2017) by Tyler Brazier (tylerbrazier
).
(Merged by Junio C Hamano -- gitster
--in commit 35898ea, 05 Jun 2017)
请参阅Tyler Brazier ( ) 的commit f15e7cf(2017 年 6 月 1 日)。(由Junio C Hamano合并-- --在commit 35898ea,2017 年 6 月 5 日)tylerbrazier
gitster
pull
: ff--rebase --autostash
works in dirty repoWhen
git pull --rebase --autostash
in a dirty repository resulted in a fast-forward, nothing was being autostashed and the pull failed.
This was due to a shortcut to avoid running rebase when we can fast-forward, but autostash is ignored on that codepath.
pull
: ff--rebase --autostash
在脏仓库中工作当
git pull --rebase --autostash
在一个脏的存储库中导致快进时,没有任何东西被自动存储并且拉取失败。
这是由于在我们可以快进时避免运行 rebase 的快捷方式,但自动存储在该代码路径上被忽略。
Update: Mariusz Pawelskiasks in the commentsan interesting question:
更新:马里乌什Pawelski要求在评论一个有趣的问题:
So everybody is writing about
autostash
when you do rebase (orpull --rebase
).But no one is taking about autostashing when you do normal pull with merges.
So there is no automatic switch for that? Or I am missing something? I prefer doinggit pull --rebase
but OP asked about "standard" git pull
所以每个人都在写
autostash
你什么时候做 rebase(或pull --rebase
)。但是当您使用合并进行正常拉取时,没有人会考虑自动存储。
所以没有自动切换?或者我错过了什么?我更喜欢这样做,git pull --rebase
但 OP 询问“标准” git pull
Answer:
回答:
The original threaddiscussing this autostash feature, it was implemented originally both for git pull
(merge) and git pull --rebase
.
讨论此自动存储功能的原始线程,最初是为git pull
(merge) 和git pull --rebase
.
But... Junio C Hamano (Git maintainer) noted that:
但是…… Junio C Hamano(Git 维护者)指出:
If the
pull-merge
were something that would induce the "annoyance" that triggered this topic, by definition, the local change overlaps with the merge, and this internal "stash pop" will touch the paths the merge touched and it is likely not result in "Dropped" but leave further conflicts to be resolved.I suspect that
pull.autostash
configuration is not a good addition because it encourages a bad, pain-inducing workflow.
In simple cases it may not hurt, but when local changes are complex, it would actively hurt than not having it, and the configuration robs the incentive to choose.The equation is somewhat different for "pull-rebase", as "rebase" insists you to start from a clean working tree, so "download and then stop" annoyance feels bigger. I have a suspicion that loosening that may be a more productive fix to the real problem.
如果
pull-merge
是会引起触发该主题的“烦恼”的东西,根据定义,本地更改与合并重叠,并且此内部“stash pop”将触及合并触及的路径,并且很可能不会导致“Dropped” "但留下进一步的冲突有待解决。我怀疑
pull.autostash
配置不是一个好的补充,因为它鼓励糟糕的、令人痛苦的工作流程。
在简单的情况下它可能不会受到伤害,但是当局部变化很复杂时,它会比没有它更积极,并且配置剥夺了选择的动力。“pull-rebase”的等式有些不同,因为“rebase”坚持你从一个干净的工作树开始,所以“下载然后停止”的烦恼感觉更大。我怀疑放松可能是解决实际问题的更有效方法。
So, regarding a classic pull-merge, it is better to:
因此,对于经典的 pull-merge,最好是:
encourage the user to think about the nature of WIP he has in the working tree before running "
git pull
".
Is it a too complex beast that may interfere with what others are doing, or is it a trivial change that he can stash away and pop it back?If the former, he will be far better off doing "
checkout -b
", keep working until the local change gets into somewhat a better shape and "commit", before pulling into the original branch.If the latter, he is better off doing:
- "
git pull
",- after finding it conflicts, run
git stash
,git merge FETCH_HEAD
andgit stash pop
鼓励用户在运行“
git pull
”之前考虑他在工作树中拥有的 WIP 的性质。
它是一个过于复杂的野兽,可能会干扰其他人正在做的事情,还是一个微不足道的变化,他可以藏起来然后把它弹回来?如果是前者,他会更好地执行“
checkout -b
”,继续工作直到本地更改变得更好并“提交”,然后再进入原始分支。如果是后者,他最好这样做:
- "
git pull
",- 发现冲突后,运行
git stash
,git merge FETCH_HEAD
和git stash pop
That being said, with Git 2.27 (Q2 2020), "git pull
" learned to warn when no pull.rebase
configuration exists, and neither --[no-]rebase
nor --ff-only
is given (which would result a merge).
话虽如此,在 Git 2.27(2020 年第二季度)中,“ git pull
” 学会了在不pull.rebase
存在配置时发出警告,并且既不存在--[no-]rebase
也不--ff-only
给出(这将导致合并)。
See commit d18c950(10 Mar 2020) by Alex Henrie (alexhenrie
).
(Merged by Junio C Hamano -- gitster
--in commit 1c56d6f, 27 Mar 2020)
请参阅Alex Henrie ( ) 的commit d18c950(10 Mar 2020 )。(由Junio C Hamano合并-- --在commit 1c56d6f,2020 年 3 月 27 日)alexhenrie
gitster
pull
: warn if the user didn't say whether to rebase or to mergeSigned-off-by: Alex Henrie
Often novice Git users forget to say "
pull --rebase
" and end up with an unnecessary merge from upstream.What they usually want is either "
pull --rebase
" in the simpler cases, or "pull --ff-only
" to update the copy of main integration branches, and rebase their work separately.
Thepull.rebase
configuration variable exists to help them in the simpler cases, but there is no mechanism to make these users aware of it.Issue a warning message when no
--[no-]rebase
option from the command line and nopull.rebase
configuration variable is given.
This will inconvenience those who never want to "pull --rebase
", who haven't had to do anything special, but the cost of the inconvenience is paid only once per user, which should be a reasonable cost to help a number of new users.
pull
: 警告如果用户没有说是变基还是合并签字人:Alex Henrie
通常,Git 新手用户会忘记说 "
pull --rebase
" 并最终从上游进行不必要的合并。他们通常想要的是“
pull --rebase
”在更简单的情况下,或者“pull --ff-only
”来更新主要集成分支的副本,并单独重新调整他们的工作。
该pull.rebase
配置变量的存在是为了帮助他们在简单的情况,但没有机制,使这些用户意识到这一点。当
--[no-]rebase
命令行中没有选项并且没有pull.rebase
给出配置变量时,发出警告消息。
这会给那些从来不想“pull --rebase
”的人带来不便,他们不必做任何特别的事情,但不便的成本每个用户只支付一次,这应该是帮助一些新用户的合理成本。
With Git 2.27 (Q2 2020), "git merge
" learns the "--autostash
" option, and the new merge.autostash
setting.
在 Git 2.27(2020 年第二季度)中,“ git merge
”学习了“ --autostash
”选项和新merge.autostash
设置。
See commit d9f15d3, commit f8a1785, commit a03b555, commit 804fe31, commit 12b6e13, commit 0dd562e, commit 0816f1d, commit 9bb3dea, commit 4d4bc15, commit b309a97, commit f213f06, commit 86ed00a, commit facca7f, commit be1bb60, commit efcf6cf, commit c20de8b, commit bfa50c2, commit 3442c3d, commit 5b2f6d9(07 Apr 2020), commit 65c425a(04 Apr 2020), and commit fd6852c, commit 805d9ea(21 Mar 2020) by Denton Liu (Denton-L
).
(Merged by Junio C Hamano -- gitster
--in commit bf10200, 29 Apr 2020)
见提交d9f15d3,提交f8a1785,提交a03b555,提交804fe31,提交12b6e13,提交0dd562e,提交0816f1d,提交9bb3dea,提交4d4bc15,提交b309a97,提交f213f06,提交86ed00a,提交facca7f,提交be1bb60,提交efcf6cf,提交c20de8b,提交bfa50c2,提交 3442c3d,提交 5b2f6d9(2020 年 4 月 7 日),提交 65c425a(2020 年 4 月 4 日),并提交 fd6852c,提交 805d9ea(2020 年 3 月 21 日)由Denton Liu ( Denton-L
)。
(由Junio C gitster
Hamano合并-- --在提交 bf10200 中,2020 年 4 月 29 日)
pull
: pass --autostash to mergeSigned-off-by: Denton Liu
Before,
--autostash
only worked withgit pull --rebase
.However, in the last patch, merge learned
--autostash
as well so there's no reason why we should have this restriction anymore.
Teach pull to pass--autostash
to merge, just like it did for rebase.
pull
: 通过 --autostash 合并签字人:Denton Liu
之前,
--autostash
只与git pull --rebase
.然而,在上一个补丁中,合并也学到了
--autostash
,所以我们没有理由再有这个限制了。
教 pull 传递--autostash
到合并,就像它为 rebase 所做的那样。
And:
和:
rebase
: useapply_autostash()
from sequencer.cSigned-off-by: Denton Liu
The
apply_autostash()
function inbuiltin/rebase.c
is similar enough to theapply_autostash()
function insequencer.c
that they are almost interchangeable, except for the type of arg they accept. Make thesequencer.c
version extern and use it in rebase.The rebase version was introduced in 6defce2b02("builtin rebase: support
--autostash
option", 2018-09-04, Git v2.20.0-rc0 -- mergelisted in batch #8) as part of the shell to C conversion.
It opted to duplicate the function because, at the time, there was another in-progress project converting interactive rebase from shell to C as well and they did not want to clash with them by refactoringsequencer.c
version ofapply_autostash()
.
Since both efforts are long done, we can freely combine them together now.
rebase
:apply_autostash()
从sequencer.c使用签字人:Denton Liu
该
apply_autostash()
函数builtin/rebase.c
是足够相似的apply_autostash()
在功能上sequencer.c
,他们是可以互换的,除了ARG的他们接受的类型。使sequencer.c
版本 extern 并在 rebase 中使用它。rebase 版本是在6defce2b02(“builtin rebase: support
--autostash
option”,2018-09-04,Git v2.20.0-rc0 --合并在第 8 批中列出)中作为 shell 到 C 转换的一部分引入的。
它选择了复制功能,因为在当时,还有一个在建项目从壳转换互动变基到C以及和他们不希望通过重构与他们发生冲突sequencer.c
的版本apply_autostash()
。
由于这两种努力已经完成很久,我们现在可以自由地将它们组合在一起。
回答by Vitaliy Ulantikov
To save few seconds for oncoming explorers, here is a summary (thanks to @VonC):
为了为即将到来的探索者节省几秒钟,这里是一个摘要(感谢@VonC):
git pull --rebase --autostash
回答by user397114
As the comment above stated, setting the two config values doesn't currently work with git pull
, as the autostash config only applies to actual rebases. These git commands do what you want:
正如上面的评论所述,设置两个配置值当前不适用于git pull
,因为 autostash 配置仅适用于实际的变基。这些 git 命令可以执行您想要的操作:
git fetch
git rebase --autostash FETCH_HEAD
Or set it as an alias:
或将其设置为别名:
git config alias.pullr '!git fetch; git rebase --autostash FETCH_HEAD'
Then do:
然后做:
git pullr
Of course, this alias can be renamed as desired.
当然,这个别名可以根据需要重命名。
回答by blueyed
With Git 2.6+ you can use the following:
使用 Git 2.6+,您可以使用以下内容:
alias gup='git -c rebase.autoStash=true pull --rebase'
This --rebase
makes git-pull use rebase
instead of merge
, so settings/options like --ff-only
won't apply.
这--rebase
使得 git-pull 使用rebase
而不是merge
,因此类似的设置/选项--ff-only
将不适用。
I am using an alias to pull with --ff-only
by default (git pull --ff-only
), and can then use gup
(from above) in case a fast-forward merge is not possible or there are stashed changes.
--ff-only
默认情况下git pull --ff-only
,我使用别名( )进行拉取,然后可以使用gup
(从上面)以防无法进行快进合并或存在隐藏的更改。
回答by CodeWizard
As you already mentioned this is the way to do it. You can use it in alias to save you typing and to use shortcut or you can use it in a single line (can be an alias as well)
正如您已经提到的,这就是这样做的方法。您可以在别名中使用它来保存您的输入并使用快捷方式,或者您可以在一行中使用它(也可以是别名)
git stash && git pull --rebase && git stash pop
git stash && git pull --rebase && git stash pop
It will do the same thing as you done but in a single line (&&) and is you set as alias it will even be shorter.
它会做和你做的一样的事情,但在一行(&&)中,如果你设置为别名,它甚至会更短。
The following lines will display the incoming/outgoing changes before you pull/push
在拉/推之前,以下几行将显示传入/传出的更改
git log ^master origin/master
git log master ^origin/master