0

I often find myself in the situation where I clone a repository, create a local branch and then have to do some initial setup work, which changes some files, before I can continue with the actual changes that I want to push later.

For example: I have cloned a Visual C++ project and created the local branch. Now I have to change the include and lib directories to correctly reference libboost. This changes the .vcxproj file, but it is obviously a change that I don't want to send back to origin/master. Only the subsequent changes are real changes.

I have considered using git update-index --assume-unchanged <file>, but that will ignore the entire file and hence it rules out the possibility of other changes to the file that I'd want to commit.

What are solutions are there? Is git rebase perhaps the solution?

Francois Botha
  • 4,520
  • 1
  • 34
  • 46

3 Answers3

2

Yes, most likely git rebase is what you want.

There's many ways to do it. One way would be to start with the changes you don't want to send, then when you are done use git rebase --interactive so you can reorder the commits and put those unrelated changes at the end.

Something like:

  • Project change (project)
  • Fix 2 (fixes)
  • Fix 1
  • Last commit (master)

I'm manually adding branch names (master, fixes and project), although you can do it without branches. For example, if you want to push all the commits of the 'project' branch as a 'fixes' branch, except the last one, even though you don't have that local branch, you can do:

git push origin project^:fixes

Another option is to have a permanent 'project' branch that has the local changes to '.vcproj.default', and then have your other branches be based on top of it:

  • Fix 2 (fixes)
  • Fix 1
  • Project change (project)
  • Last commit (master)

After you are done with your 'fixes' branch, you can rebase your branch before pushing it:

git rebase --onto master project fixes

This will basically pick the commits from 'project' to 'fixes' ("Fix 1" and "Fix 2"), and rebase them on top of master, essentially removing the "Project change" commit from the branch.

FelipeC
  • 9,123
  • 4
  • 44
  • 38
  • Thanks! The `git rebase --interactive` did what I want, but I see that it reverts the project change. This isn't crucial, but is there a way to keep the project change, but push only the subsequent commits, or is that what `git push origin project^:fixes` does? – Francois Botha May 22 '14 at 08:01
  • I don't understand what you mean by "it reverts the project change". If you have a commit that does the project change, that commit will be shown in the rebase. You cannot push only subsequent commits, but you can push previous commits, which is what project^:fixes does (push the parent of "project" as a "fixes" branch). – FelipeC May 22 '14 at 09:24
1

I'm not sure whether I got your question correctly, but I think it is not a good idea to put a config file which contains local settings directly into the repository. Instead I would add a file, lets say .vcproj.default to the repository which contains default definitions for all settings. After cloning a repository you just

cp .vcproj.default .vcproj 

and then change the settings you need to. The file .vcproj itself I would exclude using the .gitignore file.

hek2mgl
  • 152,036
  • 28
  • 249
  • 266
  • I'm not the owner of the upstream repo, so including a `.vcproj.default` file will not be accepted by the repo owner. But also, as I say, if I want to make other changes to the `.vcproj` file, I do want them to be committed. Maybe I should be looking at `git rebase`? – Francois Botha May 21 '14 at 12:02
  • As far as I understand, you currently need some modifications in your `.vcproj` file which the repo owner don't need? If so, you cannot commit this local modifications to the repo because this would require the repo owner to change them again after his next pull. I don't know which type of settings these are. If they are just paths, I would encourage you to setup the dev system in the same way as the repo owner to avoid that conflicts. Otherwise a solution like I suggested might be the best (and is widely deployed in git repos). Maybe you can discuss this with the repo owner? – hek2mgl May 21 '14 at 12:11
1

Filters can make the process painless. Here's the basic idea, you get sed to save the upstream's current values and replace them with yours on checkout, and save your current values and replace them with upstream's on checking. Can you provide a sample of the changes you want to keep from leaking?

Community
  • 1
  • 1
jthill
  • 55,082
  • 5
  • 77
  • 137
  • Thanks. I briefly encountered filters, but found them a bit advanced for me at this stage. Well, just as an example, I want to reference boost. I've made my own property sheet with the boost settings (which contains a user macro BOOST_DIR and then properties to set the include and lib directories). In general, there might be other infrastructure changes. – Francois Botha May 22 '14 at 07:21