git 您如何仅存储已添加的文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30359921/
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
How do you stash only files that have been added?
提问by peter-b
For example, a git status
gives the following:
例如,agit status
给出以下内容:
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: app/src/[....]
modified: app/src/[....]
new file: app/src/[....]
deleted: app/src/[....]
modified: app/src/[....]
modified: test/unit/[....]
modified: test/unit/[....]
new file: test/unit/[....]
deleted: test/unit/[....]
modified: test/unit/[....]
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: test/unit/[....]
Untracked files:
(use "git add <file>..." to include in what will be committed)
app/src/[....]/
app/src/[....]/
app/src/[....]/
(I have blanked the filenames)
(我已经清空了文件名)
How would I stash just the changes I have git add
ed (i.e. "Changes to be committed", not unstaged changes or untracked files) so I can transfer them to another branch instead?
我将如何仅存储我已git add
编辑的更改(即“要提交的更改”,而不是未暂存的更改或未跟踪的文件),以便我可以将它们转移到另一个分支?
回答by torek
Git's basic storage mechanism is "the commit"—in fact, all git stash
does is make a couple of somewhat unusual commits—so Nick Volynkin's answeris a correct one. It could perhaps use a bit of expansion though, and there are easier (well, potentially easier) methods.
Git 的基本存储机制是“提交”——事实上,git stash
所做的只是进行一些不寻常的提交——所以Nick Volynkin 的答案是正确的。不过,它可能会使用一些扩展,并且有更简单(好吧,可能更简单)的方法。
I'm not a very big fan of git stash
, but if you're used to using it, here's the simplest of the other methods:
我不是 的忠实粉丝git stash
,但如果您习惯使用它,这里是其他方法中最简单的:
git stash save
(akagit stash
). This writes two commits, one based on the current index and a second to hold as-yet-unstaged work-tree files. (If you need to hold untrackedfiles, you can add the-u
flag, and then the stash script adds yet a third commit. Usually you can just leave these untracked files floating around in your work tree untracked, though.) These commits are not on any branch, they are only on/in the special "stash" ref. Meanwhile you're still on the "wrong" branch, which I'll callwrongbr
below.git checkout
the branch you want these on. Now you're on the right branch.git stash apply --index
. This uses the special stash commits made in step 1, while also leaving them there (apply
) in the stash. The--index
is very important: it tells the stash script to keep the index and unstaged files separate, i.e., give you back the staged and unstaged setup you had earlier.If all goes well, you're now in a position to
git commit
the changes to the branch you want them on. The previously staged files are again staged, and the unstaged files are still unstaged, because youapply
-ed the stash with--index
. The commit will commit the staged files, leaving the unstaged files unstaged.Now you can get back on the other "wrong" branch (where you made the stash initially) and
git stash apply
orgit stash pop
with or without--index
. You may need to clean out any unstaged files (and it's safe to do so, they are still in the stash):git reset --hard
, followed bygit checkout wrongbr
, thengit stash pop
. Note thatpop
is justapply
followed bydrop
: we didn't wantto dropthe stash in step 3 (the stash has the only copy of the original modified-but-unstaged files), which is why we usedapply
there, but now we (presumably) dowant to drop the stash, so usingpop
is OK.
git stash save
(又名git stash
)。这会写入两次提交,一次基于当前索引,另一次用于保存尚未暂存的工作树文件。(如果您需要保留未跟踪的文件,您可以添加-u
标志,然后存储脚本添加第三次提交。不过,通常您可以让这些未跟踪的文件在您的工作树中浮动而不被跟踪。)这些提交未开启任何分支,它们都只在/在特殊的“藏匿”参考中。与此同时,你仍然在“错误”的分支上,我将wrongbr
在下面称之为。git checkout
你想要这些的分支。现在你在正确的分支上。git stash apply --index
. 这将使用在步骤 1 中进行的特殊存储提交,同时还将它们留在 (apply
) 存储中。这--index
非常重要:它告诉 stash 脚本将索引和未暂存文件分开,即,返回您之前的暂存和未暂存设置。如果一切顺利,您现在就
git commit
可以对您希望它们所在的分支进行更改。先前暂存的文件再次暂存,而未暂存的文件仍然未暂存,因为您apply
使用--index
. 提交将提交暂存文件,使未暂存文件保持未暂存状态。现在你可以回到另一个“错误”的分支(你最初在那里制作藏匿处),
git stash apply
或者git stash pop
有或没有--index
. 您可能需要清除任何未暂存的文件(这样做是安全的,它们仍在存储中):git reset --hard
,然后是git checkout wrongbr
,然后是git stash pop
。请注意,pop
只是apply
后面drop
:我们不希望以下降步骤3中的藏匿处(藏匿有只有原来的修改,但是,不分阶段的文件复制),这就是为什么我们使用apply
那里,但现在我们(大概)确实想放下藏匿处,所以使用pop
是可以的。
There's a big potential pitfall in step 3, though: it's possible the stash won't apply correctly. If so, you mustuse some other method. This is one reason I don't really like the stash
system: it falls down in hard cases and leaves you needing to know the tools you can use if you don't use stash
. In which case, you can just use those tools most the time ... and then use stash
as a convenient short-cut for cases where you're sure it will work.
但是,在第 3 步中存在一个很大的潜在陷阱:可能无法正确应用 stash。如果是这样,您必须使用其他方法。这是我不太喜欢该stash
系统的原因之一:它在困难情况下会崩溃,让您需要知道如果您不使用stash
. 在这种情况下,您可以在大多数情况下只使用这些工具……然后stash
在您确定它会起作用的情况下将其用作方便的捷径。
Background: a commit takes whatever is in the index now—git ls-files --cached
will show the complete contents, while git status
trims this down to the "interesting" ones and adds additional useful information—and makes a commit out of them, with all the necessary tree objects and so on. The new commit's parent commit is whatever the current commit was before.
背景:提交现在采用索引中的任何git ls-files --cached
内容 - 将显示完整的内容,同时将其git status
修剪为“有趣”的内容并添加额外的有用信息 - 并使用所有必要的树对象等进行提交在。新提交的父提交是当前提交之前的任何内容。
You want your new commit made on another branch. One way to do this is to make it now, on the current branch; then copy that commit to a new, different commit on a different branch. To do the "copy commit to new, different commit on different branch" you can use git cherry-pick
. It's true that you can use git rebase
: under the covers, it uses git cherry-pick
itself. But rebase
is not quite the right tool: it's designed for en-masse cherry-picking, and you have just one commit; and at the end it uses git reset
to move a branch label, but not quite in the way you want. You can make it work, but there are some more appropriate tools.
您希望在另一个分支上进行新提交。一种方法是现在就在当前分支上创建它;然后将该提交复制到不同分支上的新的不同提交。要执行“将提交复制到不同分支上的新的不同提交”,您可以使用git cherry-pick
. 确实,您可以使用git rebase
: 在幕后,它使用git cherry-pick
自身。但rebase
它并不是一个合适的工具:它是为大量采摘樱桃而设计的,而且你只有一次提交;最后它git reset
用来移动一个分支标签,但不是你想要的方式。你可以让它工作,但有一些更合适的工具。
Let's go back to the original problem though: you want to take the current index and use it to make a new commit, but on another branch. This would be easiest if you could just switch to the other branch now, without doing anything else, and then make the new commit.
让我们回到最初的问题:您想获取当前索引并使用它来进行新的提交,但是在另一个分支上。如果您现在可以切换到另一个分支而不做任何其他事情,然后进行新的提交,这将是最简单的。
Chances are good that you cando this. Just git checkout otherbranch
and then git commit
. There are three possible cases here:
您很有可能做到这一点。只是git checkout otherbranch
然后git commit
。这里有三种可能的情况:
The other branch doesn't exist yet. Great! Use
git checkout -b newbranch
to create it, starting from where you are now. Thengit commit
. You're done, unless you want to rebase the new branch to start from somewhere other than "where you are now". If so, usegit rebase
on the new branch. Note that you can do that rebase later, after you've taken care of the unstaged files.The other branch does exist, and—lucky you—
git checkout otherbranch
works fine. Do that and commit, and you're done. You can thengit checkout
whatever branch you want for the unstaged files.The most annoying case: the other branch does exist, but
git checkout
tells you that you'll overwrite something that you haven't committed.
另一个分支还不存在。伟大的!使用
git checkout -b newbranch
来创建它,从你现在在哪里开始。然后git commit
。大功告成,除非您想将新分支变基以从“您现在所在的位置”以外的其他地方开始。如果是这样,请git rebase
在新分支上使用。请注意,您可以在处理未暂存的文件后进行该变基。另一个分支确实存在,而且——幸运的是——
git checkout otherbranch
工作正常。这样做并提交,你就完成了。然后,您可以git checkout
为未暂存文件提供任何您想要的分支。最烦人的情况:另一个分支确实存在,但
git checkout
告诉您将覆盖您尚未提交的内容。
Case 3 is the one where you need to commit-or-stash.
第 3 种情况是您需要提交或存储的情况。
What to do here depends on what you are most comfortable with. You can, for instance, try the four-step stash
method described above as the simplest alternative.
在这里做什么取决于您对什么最满意。例如,您可以尝试将上述四步法stash
作为最简单的替代方法。
For myself, though, I would just commit now, on the "wrong" branch, then commit again (or use git stash
) to get the unstaged files out of the way. This gives me a commit I can git cherry-pick
into the rightbranch. Here's an example sequence that's likely to work:
不过,对我自己而言,我现在只会在“错误”分支上提交,然后再次提交(或使用git stash
)来清除未暂存的文件。这给了我一个可以git cherry-pick
进入正确分支的提交。这是一个可能有效的示例序列:
git commit
to make the commit, but on the "wrong" branch (let's call your current branchwrongbr
for reference below).git stash save
to save the unstaged changes (or, with-u
, untracked files too).git checkout
the branch you want the commit to have been on, e.g.,git checkout rightbr
.git cherry-pick wrongbr
. If this succeeds, good; if not, edit files as needed to clean up after the merge issues, thengit commit
the result.git checkout wrongbr
: we will now fix this up by removing the commit copied in step 4.git reset --hard HEAD^
: this drops the commit that we copied.git stash pop
(orgit stash apply && git stash drop
which does the same thing, theapply
variant simply giving you the opportunity to inspect the result before youdrop
the stash).
git commit
进行提交,但在“错误”分支上(让我们在下面调用您当前的分支wrongbr
以供参考)。git stash save
保存未暂存的更改(或者,也可以保存-u
未跟踪的文件)。git checkout
您希望提交所在的分支,例如,git checkout rightbr
。git cherry-pick wrongbr
. 如果这成功了,很好;如果没有,在合并问题后根据需要编辑文件进行清理,然后git commit
是结果。git checkout wrongbr
:我们现在将通过删除在步骤 4 中复制的提交来解决这个问题。git reset --hard HEAD^
:这会删除我们复制的提交。git stash pop
(或者git stash apply && git stash drop
做同样的事情,apply
变体只是让你有机会在你drop
藏匿之前检查结果)。
Note step 4 here: git cherry-pick
takes the named commit (the tip of wrongbr
, which contains the commit-we-want that's simply on the wrong branch), compares it with its parent, and then attempts to apply the resulting diff to the current branch. This may need to do a 3-way merge, if the files in the current branch differ a lot from their corresponding files in wrongbr
. This is the same place the complications occur in the simple case of just checking out rightbr
and committing initially. That is, we're doing this long version because the "most annoying" case occurred when we tried to just git checkout rightbr
before committing, so there's a good chance we need to do some fixing-up. This is also likely to cause problems with the original 4-step stash
method.
注意这里的第 4 步:git cherry-pick
获取命名提交( 的尖端wrongbr
,它包含我们想要的提交,只是在错误的分支上),将它与其父级进行比较,然后尝试将结果差异应用到当前分支。如果当前分支中的文件与其对应的wrongbr
. 这与在rightbr
最初检查和提交的简单情况下出现并发症的地方相同。也就是说,我们正在做这个长版本,因为“最烦人”的情况发生在我们git checkout rightbr
在提交之前尝试时,所以很有可能我们需要做一些修复。这也可能会导致原始 4 步法出现问题stash
。
回答by Nick Volynkin
Commit those files and then rebase the commit.
提交这些文件,然后重新提交。
回答by kilogic
Stash everything, but keep the index (This stash will have staged (from
git add
) and non-staged edits):git stash --keep-index
Stash the index, which is all that is left after the stash in step 1 (This is what you wanted to stash).
git stash
Pop or apply (safer) the stash that had it all, the one from step 1 (now in
stash@{1}
because the newest one is alwaysstash@{0}
).git stash apply stash@{1}
Restore the files that were originally added to the index, the ones in
stash@{0}
, by checking them out from theHEAD
git checkout HEAD ./path/to/files/to/reset ./another/path/to/other/file/to/reset
If you mess up in step 4, try
git reset HEAD --hard
to wipe out all the local changes and start again at step 3.
存储所有内容,但保留索引(此存储将已上演(来自
git add
)和非上演编辑):git stash --keep-index
存储索引,这是在步骤 1 中存储之后剩下的所有内容(这就是您想要存储的内容)。
git stash
弹出或应用(更安全)包含所有内容的存储库,即第 1 步中的存储库(现在在,
stash@{1}
因为最新的始终是stash@{0}
)。git stash apply stash@{1}
在恢复原先添加到索引中的文件,那些
stash@{0}
,从检查出来HEAD
git checkout HEAD ./path/to/files/to/reset ./another/path/to/other/file/to/reset
如果您在第 4 步中搞砸了,请尝试
git reset HEAD --hard
清除所有本地更改,然后从第 3 步重新开始。