2

I've checked out from a remote branch and modified some of the files. However I do not wish to add them in the next commit since they are applicable only to my local configuration; in fact, I always want them to be uncommitted. For that reason, I've applied git update-index --assume-unchanged on these files. However, now I have problems with checking out from branches where these files differ from my local ones: enter image description here

If I click on 'Smart Checkout' (which is what I need), it throws an error:

Couldn't checkout origin/master: Your local changes to the following files would be overwritten by checkout:

Even if I click on "Force Checkout" it will throw:

Couldn't checkout origin/master: Entry '.gitignore' not uptodate. Cannot merge.

So how can I check out from other branches, while keeping local changes?

pkamb
  • 33,281
  • 23
  • 160
  • 191
arslancharyev31
  • 1,801
  • 3
  • 21
  • 39
  • 1
    As for .gitignore you can add local ignore patterns to .git/info/exclude and keep the one in project unchanged – max630 Jul 19 '17 at 12:29
  • 1
    and by the way what you rather need is [skip-worktree](https://stackoverflow.com/a/13631525/2303202) – max630 Jul 19 '17 at 12:38
  • Looks like skip-worktree is the thing I was initially looking for. Please consider making that an answer, so that I could accept it. – arslancharyev31 Jul 19 '17 at 14:20
  • 1
    I tried to reproduce it and it seems to be a bit complecated. What I made to work I apparently [have already written once](https://stackoverflow.com/a/37066742/2303202). So adding another same answer is probably not good. – max630 Jul 20 '17 at 05:38

2 Answers2

2

I always steer people away from assume-unchanged, for exactly this reason. Your best bet is to find a different way to keep your changes out of the repo.

From your error message, it seems the .gitignore file is one of the files in question. Non-shared/local ignore rules don't belong in .gitignore; they belong in .git/info/exclude.

Other cases may have to be dealt with individually. A common case would be local config files. A typical solution is to source-control only a template, with the expectation that developers will create the actual config file locally (at a path that's either ignored or outside the repo work tree).

If you have local/unshared versions of code, I'd start by revisiting the reasons for that. If it's necessary, then the best solution may be to use a build process that lets you swap in code from outside the worktree.

The bottom line is, if you've told git to track the file at a path, it's going to try to do just that.

Mark Adelsberger
  • 42,148
  • 4
  • 35
  • 52
  • The reason I'm bothering with all these ceremonies is that I just want to send bug-fixing pull requests to various GitHub repositories, without committing any other modifications (like build.gradle files in this case). So is there a more convenient way to do that? – arslancharyev31 Jul 19 '17 at 13:17
  • 1
    I think I would do it by making bugfixes I intend to share on branches rooted at the upstream (presumably checked out to a separate worktree), which I would then merge back into my own work lines. – Mark Adelsberger Jul 19 '17 at 13:52
1

To checkout the other branch, Git needs to know about the changes, for each file:

git update-index --no-assume-unchanged EACH_FILE

Stash those changes:

git stash save "Save local conf"

You can now checkout to your other branch:

git checkout myotherbranch

Finally, you can restore your local changes if you want them in your other branch:

git stash pop

And, as mentioned by Mark, I'd use --skip-worktree to protect those files from changes. Why? See here

saccodd
  • 972
  • 9
  • 23