问题
I have my local repo in a state that forbid me to either commit, stash, checkout to another branch or even discard changes. So I'm just stuck.
I will try to describe what steps brought me to this situation, as far as I remember.
Please, take a seat.
A not so long time ago, in another computer far, far away... an other dev normalized crlf in the project according to: https://help.github.com/articles/dealing-with-line-endings
In the while (you know, speed of light...) I made some changes locally, commited, and pulled.
When I pulled Git said:
error: Your local changes to the following files would be overwritten by merge:
wp-config.php
wp-config.php
was earlier removed from the index using git update-index --assume-unchanged wp-config.php
since its a template config file adapted to each local environment.
The base "template" can change. Nothing surprising. Here what I planned:
- reindex
wp-config.php
stash
my own config changespull origin master
stash apply
my config back
Things went wrong at step 3. git pull origin master
still raised the error above, as if the stash was ineffective.
git status
said wp-config.php
had changes not staged for commit. That surprised me a bit after a stash.
Since I stashed my changes I ran git checkout -- wp-config.php
... but without any effect! File was still not staged for commit.
Since I was becoming mad, I created a new branch my-config, added and commited wp-config.php
into it, then switched back to master, deleted wp-config.php
(using git rm
), and merged origin/master... with success!
So now that master was up to date and clean, I planned to restore my own config without the help of Git (editing the file manually).
Since I wanted to know what happened, I switched to my-config branch, and tried here a very simple manipulation:
git stash
git stash apply
And guess what? stash apply
failed saying:
error: Your local changes to the following files would be overwritten by merge:
wordpress/license.txt
wordpress/readme.html
...
(all the files that where modified by the crlf conversion)
And now I'm stuck on my branch (and plan to saw it, Francophones will understand ;)) since:
git stash apply
,commit
andcheckout master
gives the error abovegit stash
produces a stash entry but doesn't change the unstaged states- and
git checkout -- <file>
neither removes the unstaged state
The only thing I can do now is to delete all these files (using the OS rm
) to be able to go back to the master branch.
True story.
I would love to understand what happened on the master branch, then on my-config branch, and what brought me in such situations (I suspect using stash on crlf converted file).
Important notes:
- I run on linux
git core.autocrlf
is oninput
- my
.gitattributes
is the same as the one in "dealing-with-line-endings" article - I'm relatively new to Git (2nd day living with it)
When I did stash
on my-config branch it outputed:
warning: CRLF will be replaced by LF in wordpress/license.txt.
The file will have its original line endings in your working directory.
... (one for each crlf converted file) ...
Saved working directory and index state WIP on my-config: dbf65ad my config -- should not be pushed
HEAD is now at dbf65ad my config -- should not be pushed
(dbf65ad
is the only commit I did on my-config branch)
回答1:
After some research i guess the following happened. Your workmate changed the lineendings which caused the first pull-conflict.
That's why you stashed your work, pulled the stuff (now without problems) and started to apply the stash again.
With invoking git stash apply
git starts a recursive merge in of your stashed changes.
The error-message just tells you ran into a merge-conflict. According to the developer's stash-documentation this may be resolved by a git stash drop
after resolving the conflicts:
"Applying the [stash] can fail with conflicts; in this case, it is not removed from the stash list. You need to resolve the conflicts by hand and call
git stash drop
manually afterwards."
Conclusion: If the configuration of the line-endings must be done in a existing project it seems to be best practise to do so by using a .gitattributes
in your project-folder. Since it gets distributed with your line-ending-change-commit, it will avoid the headaches switching your current work to the new normalization-standard.
Changing line endings within projects & .gitattributes
According to the developers documentation of .gitattributes you can change the line-endings for all files (in the active branch) with the following steps:
$ echo "<<filepattern>> eol=lf" >>.gitattributes
$ rm .git/index # Remove the index to force Git to
$ git reset # re-scan the working directory
$ git status # Show files that will be normalized
$ git add -u
$ git add .gitattributes
$ git commit -m "Introduce end-of-line normalization"
Replace <<filepattern>>
with a pattern that matches your source files - in your case *.py
for python-files (a good pattern-explanation is given in this .gitignore-description).
If you have more than one filepattern to add, you may add several line-ending-definitions to the .gitattributes
.
Attention: Since the second step requires to delete the .git/index (which is branch-specific) this must be done in every single branch you'd like to keep.
If you have many branches to process, you might consider writing a short script iterating through your git branches.
回答2:
The best way to reset your local module is to use
git clean -f -x -d
This effectively removes all untracked changes to your local module and puts it back in a 'vanilla' state.
-f
clean files.-x
clean files normally ignored by .gitignore.-d
clean directories.
Now run git reset --hard origin/<BRANCH_NAME>
. This will reset your branch to the state of the remote.
git status
at this point should tell you:
# On branch master
nothing to commit (working directory clean)
If you have your actual changes stashed you should then be able to git stash apply
to put them back correctly.
If git stash show stash@{0}
shows more changes than you expected you can just apply the ones you want to see with git checkout stash@{0} -- <filename>
.
Hope this helps
回答3:
First, regarding the GitHub help page, I would seriously recommend setting:
git config --global core.autocrlf false
Let reserve eol modification to explicit declaration in .gitattributes files instead of a global magic rule: keep core.autocrlf to false.
Second, you can see if you observe the same eol modifications on git stash
with git update-index --skip-worktree.
来源:https://stackoverflow.com/questions/17123998/stuck-repo-using-stash-after-crlf-normalization