问题
Say I have a git repo whose working tree and/or index is "dirty" (i.e. I have local modifications that have not yet been committed or stashed) and I'm tempted to do a "git pull" without first committing or stashing. (Alternatively, say I'm introducing a new team member to git and they are tempted to run "git pull" when their local repo is "dirty".) I'm wondering how safe it is to do a "git pull" in this case. If it's unsafe, what's the worst thing that can happen? Does it matter if I'm pulling from a trusted vs untrusted source?
My investigation so far suggests a confusing range of ideas on what I'd assumed would be a fairly straightforward question.
To start with, the git-stash manpage makes it sound like git pull is pretty safe, and will abort if you're in a situation where something might go wrong:
Pulling into a dirty tree
When you are in the middle of something, you learn that there are
upstream changes that are possibly relevant to what you are doing.
When your local changes do not conflict with the changes in the
upstream, a simple git pull will let you move forward.
However, there are cases in which your local changes do conflict
with the upstream changes, and git pull refuses to overwrite your
changes. In such a case, you can stash your changes away, perform a
pull, and then unstash, like this...
This actually seems to be what happens too, in my simple tests so far.
Also perhaps implying that "git pull" is pretty safe, the Git Extensions toolbar for Visual Studio has a prominent pull button that does not do a check for dirtiness before shelling out to "git pull". (If I were designing a Visual Studio toolbar, I would try to avoid making it particularly easy to shoot yourself in the foot.)
The git-pull manpage doesn't make my "git pull" sound dangerous, though it suggests it's not a best practice:
If any of the remote changes overlap with local uncommitted changes,
the merge will be automatically cancelled and the work tree untouched.
It is generally best to get any local changes in working order before
pulling or stash them away with git-stash(1).
But then you can also find advice that pulling into a dirty is very bad, e.g.:
Avoid git-pull!
git-pull should never get invoked if you have dirty files lying around or if your branch is ahead of master.
This will always lead to some dirty artifacts in the commit history
Is there an easy answer to which perspective is best, or is this somehow a case-by-case thing?
Followup: Would using "git pull --rebase" rather than just "git pull" change the answer at all? Rebasing may have its own pitfalls in some cases, but so far my guess is that having a dirty working tree/index wouldn't make a rebase more problematic than it otherwise would be.
回答1:
No offense to the people maintaining the Apache DeltaSpike project, but I'd trust what the Git man pages say about Git over the contents of the Delta Spike wiki.
Also note that in the quoted text (emphasis mine):
git-pull
should never get invoked if you have dirty files lying around or if your branch is ahead of master. This will always lead to some dirty artifacts in the commit history.
The "dirty artifacts in the commit history" are Git merge commits. This happens any time you merge branches instead of rebasing the contents of one branch on the other. Whether or not these merge commits are "dirty" depends on your project, your organization and its opinion and policies.
In any case, git-pull
is never a dangerous operation. As documented, it will not destroy any of your history or work in progress.
回答2:
In my experience, it's absolutely safe (I am using git for about 4 years). If you have uncommited changes, it usually just fails telling you that you have a dirty working copy.
回答3:
git pull is simply git fetch + either rebase/merge, the automated merge can create noise or unintended results. (Example of noise: You don't need 10 merge commits when all you did was to add a single line to the same file 10 times.) If the uninitiated simply does a git pull and push back without checking, the noise will be checked in.
I would just say that the new team member is more likely to be disoriented after a git pull on a dirty working tree, whether it is safe or not, it will depend on the response (checking the results after every pull will be a good start).
回答4:
So far I'm not sure this actually bears on git pull (which sounds like it pre-detects whether there could be merge conflicts and aborts if there could), but note at least tangentially that merging (i.e. doing git merge) into a dirty working tree can apparently limit your ability to "undo" your merge in the case that the merge goes bad. In particular, from the git-merge manpage:
[merge] --abort
Abort the current conflict resolution process, and try to
reconstruct the pre-merge state.
If there were uncommitted worktree changes present when the merge
started, git merge --abort will in some cases be unable to
reconstruct these changes. It is therefore recommended to always
commit or stash your changes before running git merge.
回答5:
Scenario A:
If the pulled commits would conflict with the uncommitted changes in your working tree, then Git would abort and save you from making a mess of your repo.
Scenario B:
If the pulled commits would conflict with committed changes in your repo and you also have uncommitted changes in your working tree that would not conflict, then you'd end up with a mess on your hands. You would have to resolve the conflicts and commit without losing track of the changes that were in your working tree prior to pulling.
Scenario B comes up for me sometimes after introducing new team members to Git. A common mistake of new members to my team is accidentally/negligently changing files in our network drive repos, rather than on their local clones like they're supposed to, and they also forget to commit those changes!
As an aside, one way to protect yourself from mistakes made by your team is to always pull to a clean local repo first, deal with any conflicts locally, and then pull from your local repo to the repo you share with your team. This extra step prevents Scenario B and either makes the dirty tree transparent to you or, worst case, presents you with Scenario A. Thankfully, Scenario A can be dealt with as a normal conflict, without the headaches of Scenario B.
回答6:
git fetch
And then merge, rebase or reset depending on what was fetched from the server. You can use pull and it will not destroy work in progress. However the former method is preferred.
来源:https://stackoverflow.com/questions/9855946/is-it-safe-to-git-pull-when-my-working-tree-and-or-index-is-dirty