Reputation: 328770
I have the following situation: A coworker has committed a bunch of files with Windows line endings. We have a .gitattribute
which removes the Windows line endings during commit
.
That means after pull
, I have dozens of files that are marked as "locally changed" when they weren't. I can't check them out since Git will take the (broken) file out of the repo (where it has Windows line endings), fix the line endings to end up with a file that's always different to what is currently in the repo.
One member of the team has fixed those files and committed and pushed them.
This question answers my question at the price of losing all local commits (i.e. everything that hasn't been pushed, yet): How do I force "git pull" to overwrite local files?
How do I pull without losing my local commits?
This is my Git repo on the server:
A --> B --> BAD1 --> FIX1(HEAD)
BAD1
contains bad commits, FIX1
fixes them.
This is what I currently have on my disk:
A --> B --> BAD1 --> LC1 --> LC2(HEAD)
\---> FIX1
I arrived here by git pull --rebase
. before that command, I had:
A --> B --> LC1 --> LC2(HEAD)
What I want to end up with is:
A --> B --> BAD1 --> FIX1 --> LC1 --> LC2(HEAD)
Upvotes: 1
Views: 171
Reputation:
The answer you linked to is similar to what you need to do. Since your other coworker already fixed the line-endings and pushed the changes, you can just fetch
the new changes from the origin, then merge
them into your local work, or rebase
your local work on top of them:
git fetch <remote>
git checkout <local-branch>
# Merge changes
git merge <remote>/<remote-branch>
# Or rebase
git rebase <remote>/<remote-branch>
fetch
will never overwrite work on you local branches, all it does is update your remote-tracking branches. In fact, pull
is just a fetch
followed by a merge
.
Since your working copy has modified files (only because of the line endings), I guess it's preventing you from rebasing. So you can simply cleanup your working copy, do a hard reset back to a previous good state, merge in the fixed commit, then cherry-pick your local commits back on top (using their sha IDs).
Putting that all together, it looks like this:
git checkout -- .
git reset --hard B
git merge <remote> <branch>
git cherry-pick LC1 LC2
When you do a hard reset, none of your commits are actually deleted by git right away. Git keeps all commits that aren't reachable from a branch or reference around for a set period of time (the default is 2 weeks), before finally garbage-collecting them from the repo. You can initiate an early garbage-collection by running git gc
, but obviously you don't want to do that right now in your case.
Because none of the commits are actually deleted right away, you can still reference them using their sha IDs, which is why you can cherry pick them back on top of your branch after you've merged in the fixed commit.
Upvotes: 1