As soon as you changed the content of a fake-symlink-file without also changing its mode from symlink to regular file and committed the result, you made a blob that can't be extracted on an OS with real symlinks, because you have an object that is supposed to be a symlink but its content is too long to be a pathname. The web interface is not doing you any favors by hiding this problem.
You're probably going to have to back up to that commit, fix it, and re-commit everything after it. git rebase -i
will help, but it still might not be easy, especially if you've made more changes to the files while they were in this bogus symlink-but-not-really-a-symlink state.
Supposing that the bad commit is abcdef123
, you need to do this:
git rebase -i 'abcdef123^'
which will put you in an editor with a list of commits. abcdef123
should be on the first line. On that line, change pick
to edit
. If there is more than one bad commit, change all of them to edit
. Save and exit the editor.
Now you'll be back in the point in time where you committed the bad file. This is your chance to alter history, putting things right that once went wrong. Inspect the commit with
git show
and undo the bad part by restoring the original symlink pathname into the file and git add
ing it. Or you could really get rid of the symlink properly with git rm
, then create a new file and git add
that. If you choose the first option, be aware that the content of a symlink is just a pathname. It's not a text file - it doesn't have a newline on the end. If you edit it with a text editor that adds a newline, you'll have a broken symlink (pointing to a file with a newline in its name).
After you've done your git add
, reinsert the fixed commit into its place in history:
git commit --amend
git rebase --continue
If you changed multiple commits from pick
to edit
you'll have to repeat that procedure for each one. The final git rebase --continue
will bring you back to the present.
If you are at a past commit during the rebase and you discover that the whole commit is bad (it did nothing else besides replacing a symlink with the unmodified content of the file it points to), then you can git rebase --skip
instead of amending and continuing. If you know ahead of time that this is going to happen, you can just delete the bad commit from the git rebase -i
list instead of changing its pick
to edit
.
If you have multiple branches affected by the bad commit(s), you will have to repeat the whole procedure for each branch. Check out a branch, run the git rebase -i
to completion (which is when git rebase --continue
says "Successfully rebased"), then check out the next branch and do it again.
In the future, when splitting your development work between Windows and a real OS, do your Windows work with cygwin. Inside cygwin, symlinks are symlinks and you can't mess them up like you did.
mode
for this files in git ins NOT120000
(what should stand vfor symlinks) instead it should be e.g.100644
. Read the orginal post for more details about the symlink mode at stackoverflow.com/a/18791647 – Rotherham