Skip to content

Subtree Based Workflow

ande3577 edited this page Jun 6, 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.

In order to create a new subtree project from an existing codebase, see [Split a Project into a Subtree Project](Split a Project into a Subtree Project).

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.

  8. In the applications readme file, document the presence of a subtree with a line with the following form:

    Includes following subtrees:

    Shared Library Name: shared library repository url - shared library path within project (shared_library_branch)`

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. Send a pull request following the instructions of the shared library maintainer. Include the location of your shared repository and the name of the branch containing the shared library code.

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 a variant of the [Simultaneous-Branch-Workflow](Simultaneous Branch Workflow) 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. Fetch the newest version of the shared library

  4. Rebase the current shared library branch on the newest shared library version

    git rebase shared_library/master

  5. Resolve any conflicts

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

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

  7. Verify the merge and commit.

  8. Send a pull request following the instructions of the shared library maintainer. Include the location of your shared repository and the name of the branch containing the shared library code.

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. Rebase your shared library branch on the new version

    git rebase shared_library/master

  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.