Skip to content

Subtree Based Workflow

ande3577 edited this page May 27, 2012 · 14 revisions

Git Subtree Workflow

For a more complete explanation, see: http://git-scm.com/book/ch6-7.html

This description assumes a familiarity with basic git operations (commit, push, pull, etc). These standard operations can be done either through the command line or with a git GUI tool of choice (Egit, tortoiseGIT, etc). The read-dir and merge -s subtree operations must be done via the command line, since as of this writing no git GUI appears to implement subtree support.

See [Why-Use-Subtree](Why Use Subtree) for an explanation of the benefits of a subtree based system.

Importing a shared project

  1. Ensure that the shared library has an accessible remote git repository.

  2. Create a new project.

  3. Add the shared libraries remote repository location as a remote to the super project

  4. Fetch from the libraries remote repository.

  5. Create a new local branch from the remote tracking branch (e.g. shared_library_branch)

  6. Run the following command from the command line (substituting the appropriate remote and branch name. Prefix is the subdirectory the library will be loaded into):

    git read-tree --prefix=”SharedLibrary/” -u shared_library_branch

  7. The shared library will now appear in your working directory.

Importing updates to a shared library

  1. Ensure the shared library's remote repository is currently up to date.

  2. Fetch the changes from shared library remote.

  3. Checkout the shared library branch.

  4. Merge the changes from the shared library, resolve any conflicts

  5. With your super projects current target branch checked out, run the following command:

    git merge --squash -s subtree --no-commit shared_library_branch

    This command includes the following optional parameters:

     i. The --squash command  will remove all intermediate history from the shared library (it will show only the most recent commit
    
     ii. The --no-commit option will not actually commit the merge to git, this will allow you to preview the results of the merge first and add your own commit message
    
  6. Commit the results of the merge with a meaningful comment.

Notes:

  • Step 3-4 can be skipped and the following it command can be used:

    git merge --squash -s subtree --no-commit shared_library/master

    Where shared_library/master points to the remote tracking branch.

  • In some cases the git subtree may not be able to determine the correct path to use for merging. In this case provide an explicit command using the following:

    git merge --squash -s recursive -X subtree="SharedLibrary" --no-commit shared_library/master

    Where SharedLibrary is the path the shared code, and shared_library/master is the local or remote branch to use to perform the merge.

Make a change to the shared library from your project

  1. Modify the local library and commit your changes.

  2. Create a local branch based on a remote branch from the shared library.

  3. Checkout out above branch

  4. Run a subtree merge as shown below:

    git merge --squash -s subtree --no-commit master

    *See Importing updates to a shared library for a list of parameters

  5. Push the changes to the shared library repository

    *Do not push the changes to a long-term branch on the shared library. Instead, create a new branch including your project name that can be merged in later.

Cloning a repository that includes subtrees

  1. Clone the repository as normal.

  2. You will now get the cloned project's version of the shared library, even if those changes have not been published, or the shared repository is unavailable.

    i. This is a key difference from a git submodule, where all commits of a submodule must be pushed to the shared repository in order to be obtained when cloning.

    ii. The reference to the shared project must still be added to the cloned repository in order to correctly link the two together.

  3. Add the shared project's remote repository to the cloned project

  4. You will now be able to pull and push changes to remote repository as listed above

Potential efficiency enhancement

Changing between your main project branch and the local branch for the shared library can require repeatedly deleting and recreating your entire project contents. This can not only take a long amount of time, but can require a full rebuild on your project when switching back. An alternative approach is presented below.

Begin by creating a clone of your project for each shared repository being used. Select the local branch corresponding to that repository as the starting branch. Prevent confusion by deleting the local shared respository branches from your main project, and deleting all other branches from each clone.

###Publishing changes to the shared library

  1. Commit your project with all changes to the shared repository and push the current version to your shared repository

  2. From the corresponding shared library clone, fetch the newest version of your projects main branch

  3. Perform subtree merge using the remote tracking branch using the following command:

    git merge --squash -s -subtree --no-commit origin/master

  4. Verify the merge and commit.

  5. Push the change to the remote branch for the shared library. Remember to push to a seperate branch rather than the one of the permanent branches.

Updating the shared library

  1. Ensure that the shared library clone's repository is up-to-date with any changes to your project folder (see the procedure above)

  2. From the shared library clone of your project, fetch the most recent shared library version

  3. Merge the change into the local branch for that shared reference

  4. Push this branch to the remote repository of your project

  5. From your projects main repository, fetch the branch you just committed.

  6. Perform a subtree merging using the remote tracking branch as shown below:

    git merge --squash -s subtree --no-commit origin/shared_library_branch

  7. Verify the merge and commit your project with the up to date version.