Manage Local Versions with Git

July 31, 2008 – 22:38 | misc | Tags:

In almost every project I have worked on, there were always a couple of files here and there that are checked into the version control, but have to be modified according to everyone’s local environment. With conventional centralized version control, they can become quite a pain to manage — we have to condition ourselves to remember to ignore them during diff’ing, always be careful not to check the local versions in, and deal with the mess when we have to actually check into those files changes which do need to be shared. This blog post tries to present a approach that makes it easier and less error prone, using git.

The general idea of this approach is to maintain two separate branches — one for synchronizing with the rest of the world, and the other for managing the local changes — and sync between the two using the powerful git-rebase.

  1. Say we have just cloned the team repository:

        master
        v
    A-B-C
  2. The next step is getting ready to start hacking locally:

    (Nadeem Bitar points out below that "checkout -b" is a better way. Thanks!)
    $git branch local && git checkout local
    $git checkout -b local
    $make whatever local changes
    $git add <the files changed>
    $git commit -m 'LOCAL_HACKS: my env'

    Now we have (* indicates we are currently on the local branch, and the L? commits are the ones containing local changes):

        master
        v
    A-B-C-L1-L2
             ^
             local*
  3. So we stay on the local branch, continue to work on the real cool features that we are here to really implement, and keep committing just like usual. After a while, we end up with:

        master
        v
    A-B-C-L1-L2-E-F
                  ^
                  local*
  4. This is where the interactive rebase comes in so we can move the local changes L1 and L2 to the tip of local:
    $git rebase -i master
    (use our favorite editor to rearrange the commit lines)

    Now we have:

        master
        v
    A-B-C-E'-F'-L1'-L2'
                    ^
                    local*
  5. The last step is to bring master up to speed with only the commits we intend to publish:
    $git rebase local~2 master  # local~2 is F' in this scenario.

    So the end state is:

             master*
             v
    A-B-C-E'-F'-L1'-L2'
                    ^
                    local

An alternative is use git-cherry-pick to move the non-local commits from local to master. Although it’s easier than the approach above only when there is just one or two commits that need to be moved over.

Trackback from your site, or follow the comments in RSS.
  1. 3 Responses to “Manage Local Versions with Git”

  2. For cases where a file needs to edited in local workspace one can actually check in a template of the file and then users can create their own version of it. I would actually suggest the template way.

    For example db-config.properties is a file that would require one to sepcify their subjective connection parameters I would add a db-config.properties.template and have users create their own version of it. Additionally I would also add it to git’s ignore list (.gitignore) so that the file does not show up in index and does not affected due to git reset command.

    By Imran M Yousuf on Aug 4, 2008

  3. You can use git checkout -b to create a branch and switch to it.

    By Nadeem Bitar on Aug 5, 2008

  4. @Imran,

    Yes, templates work. I have used those before – when there wasn’t git. :-) Although they do come up short compared to actually having the local files:

    1. An obvious one: the local files aren’t git-managed. So if I want to clone the repo _locally_, I’d have to manually copy them over.

    2. When db-config.properties.template changes, the change has to be manually merged to db-config.properties, whereas with git there is a good chance it’ll get automatically merged.

    3. Not all the files can made into templates – for instance, Eclipse’s .class and .project files.

    @Nadeem,

    You are right. Git checkout -b would be more straightforward.

    By Jing Xue on Aug 7, 2008

Post a Comment