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:
wp-config.php
stash
my own config changespull origin master
stash apply
my config backThings 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
and checkout master
gives the error abovegit stash
produces a stash entry but doesn't change the unstaged statesgit checkout -- <file>
neither removes the unstaged stateThe 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:
git core.autocrlf
is on input
.gitattributes
is the same as the one in "dealing-with-line-endings" articleWhen 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)
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With