-1

I am trying to understand this behavior of git. It has to do with file removal and preservation of a commit.

Suppose I am working in a branch called fork1 at the latest point. I get there by doing "git checkout fork1". I then delete a file called first.bsh. (Not git rm, just rm). If I do "git checkout fork1", it produces a message:

Already on 'fork1'
D       first.bsh

noting the file is missing. It is not restored, despite the checkout.

I then do "checkout master" and then "checkout fork1". At this point, the file is restored. It appears that the order of the commands affects what "checkout fork1" does. That is surprising and does not seem like desirable behavior. It's sort of "respecting" my deletion in one case, but not the other. What is the logic here?

Anthony Mannucci
  • 277
  • 2
  • 12
  • 3
    Are you sure you are only saying `git checkout master; git checkout fork1`? Because if the file is different in master from what it is in fork1's tip, then git will prevent you from checkiing out... and then you would have to use -f which is what is restoring the file. If the fire is the same between master and fork1's tip, then you should be able to switch from one to the other keeping the file as removed in your working tree. – eftshift0 May 25 '20 at 20:51
  • I believe the description is accurate. I did not manipulate the file in any way that I am aware of. I don't see any relevant aliases in my .gitconfig file. Version is git version 2.26.2.windows.1 . Either behavior could be justified, but different behavior depending on order of commands is not justified. It would appear that "git checkout master" makes a change to the internals of git, that then changes how git executes "git checkout fork1". – Anthony Mannucci May 25 '20 at 21:13
  • Why would the command you used restore the file? To restore the file one must pass the file location. `git checkout -- first.bsh` https://git-scm.com/docs/git-checkout – evolutionxbox May 25 '20 at 21:18
  • It appears that if one is at fork1, "git checkout fork1" does one thing, but if on another branch to start, "git checkout fork1" does something else. I believe the file is restored because it's part of the commit. The latest fork1 commit has that file in there. The deletion would likely be accidental. It makes sense that a checkout would restore the file, if checkout restores a commit state. Isn't that one way that source code is controlled? Accidental deletions are recoverable? – Anthony Mannucci May 25 '20 at 21:23
  • I think you should paste the whole flow of commands (checkouts, rm and status) in the question so that we can see how you did it. – eftshift0 May 25 '20 at 21:23
  • Here it is: $ git checkout fork1 Already on 'fork1' $ rm first.bsh $ git checkout fork1 Already on 'fork1' D first.bsh $ ls first.bsh ls: cannot access 'first.bsh': No such file or directory $ git checkout fork1 Already on 'fork1' D first.bsh $ ls first.bsh ls: cannot access 'first.bsh': No such file or directory $ git checkout master Switched to branch 'master' $ git checkout fork1 Switched to branch 'fork1' $ ls first.bsh first.bsh* – Anthony Mannucci May 25 '20 at 21:28
  • See https://stackoverflow.com/q/22053757/1256452 for the gory details, but what's happening is that you have a modified index, the modified index is carried across the first checkout, and then lost across the second. When and whether this will happen depends on the contents of each commit *and* the modified index. – torek May 26 '20 at 00:23

1 Answers1

1

When you change the active commit with git checkout : git will try to reconciliate your local changes with the difference "old HEAD <-> new HEAD".

If your local modifications say "file first.bsh is deleted", and file first.bsh does not exist on master, git will say "hey ! we're good !" and diligently move your active commit to master.

The difference in behavior is between changing active commits -- the "keep pending changes" strategy is a heuristic and can be lossy -- and staying where you are.


The safest bet is to commit your work or run git stash before switching.

LeGEC
  • 46,477
  • 5
  • 57
  • 104
  • Thank you. The definitely enlarges my understanding. It seems that removing files sort of "slips under the radar". If a file is modified after the commit, git aborts the checkout of a different branch. A git stash saves the changes and the checkout can then proceed. – Anthony Mannucci May 26 '20 at 00:10