Sharing External Code using Git Subtree

ACME plans to make extensive use of the 'git subtree' capability for components which are also developed by other organizations outside ACME.  The use of git subtree allows most ACME development to take place within the ACME repository, in a seamless manner, with no knowledge of the fact that the code may or may not part of a subtree.  But the use of a subtree allows ACME, when necessary, to use git merge utilities to bring in new code from the external repository or to share ACME code with the external repository.  

This page is for integrators who will be bringing in code or changes to code from an external repository or will be tasked with sharing some portion of ACME code externally. This page describes the process where the code will be integrated into the ACME repository as a git subtree. There are two workflows related to creating the initial git subtree within ACME:  Inserting in a new external into ACME as a subtree, replacing original ACME code with an external subtree.  There are two workflows for working with an established git subtree:  merging in changes from an external into an ACME subtree, and pulling changes from an ACME subtree to merge back to an external. Each workflow is outlined below followed by sections showing details for various workflow step types. Read the conditions at the top of each workflow to be sure to choose the correct one. 

The `git subtree` command was introduced in version 1.7.11, so it's use requires at least that version.

Some Terminology

<external_subdir> refers to the place in the ACME tree where the external code resides (or will reside).

<external_name> is a name you give to the external so that you can refer to the external repository. 

<external_url> is the URL for the external repository.

<external_repo> is the remote name for an external repo (or a fork of the external repo) that you have write access to. Note, it might be the same as <external_name>, but in the event you don't have write access to that repo, it will be different.

<external_commit> refers to a branch name (<external_url>/<branch_name>), a commit, or a tag name from the external repository.

<external_branchname> refers to local branch created with git subtree split in preparation for merging with an upstream repository.

<external_mergebranch> refers to the branch on the external used for merging changes. Depending on the rules for the external, this may be master or an integration branch.


Insert new external subtree into ACME (one-time setup)

This workflow should only be used if ACME decides to adopt code from a new external. The resulting subtree will be a new subdirectory within ACME. This will typically be done once to be followed by the 'Merge Changes' workflow below.

  1. Create and switch to a branch in which to conduct the work. Be sure to follow the branch naming conventions and other development practices. The branch name should follow the form github-username/component/component.<version>-import.
  2. Test and submit a pull request as defined in the development practices page.

Replace original (unmodified) ACME code with external subtree (one-time setup)

This workflow should only be used if original (v0.0) ACME code is being replaced with code from an external. This will typically be done once to be followed by the 'Merge Changes' workflow below.

  1.  Verify that the external code in the ACME repository has been not been modified since the initial commit (cd <external_subdir>; git diff --name-only v0.0 .). If there are changes (non-blank output), follow the 'Merge changes from external into ACME subtree' workflow below.
  2. Create and switch to a branch in which to conduct the work. Be sure to follow the branch naming conventions and other development practices. The branch name should follow the form github-username/component/component.<version>-import.
  3. Add external git repo to as a remote in your local repository copy (git remote add -f --tags <external_name> <external_url>).

    1. Example:  git remote add -f --tags MCTorigin https://github.com/MCSclimate/MCT
  4. Check your work (git status)
  5. Test and submit a pull request as defined in the development practices page.

Merge changes from external into ACME subtree (typical workflow)

This workflow may be used repeatedly anytime new work is to be moved from an external into an ACME subtree.

  1. Create and switch to a branch in which to conduct the work. Be sure to follow the branch naming conventions and other development practices. The branch name should follow the form github-username/component/component.<version>-import.
  2. Add external git repo to as a remote in your local repository copy (git remote add -f --tags <external_name> <external_url>).
  3. Merge  from external git repo to ACME (git subtree merge --squash --prefix=<external_subdir> <external_commit>).
  4. Commit the change (git commit).
  5. Test and submit a pull request as defined in the development practices page.

Split changes from an ACME subtree for merging with an external repo

NOTE:  If you have to edit code that is in a subtree, commit those separately from other changes.

This workflow is to be used any time changes to an ACME subtree should be shared with the source external repository. For example, consider a bug fix made in the ACME MCT code. This workflow would allow contributing that fix upstream to MCT. Note that this workflow should not be used for the case where the ACME subdirectory was not brought into ACME as a subtree. That workflow is beyond the scope of this document.

  1. Pull changes from the ACME subtree into a new branch (git subtree split -P <external_subdir> -b <external_branchname>).
    1. NOTE:  if the external_subdir has received more then one merge from the external, add --ignore-joins to the above.
  2. If necessary, add remote for updated external (If git remote does not list your remote, add it with git remote add -f --tags <external_name> <external_url>).
    1. Similarly, add a remote for <external_repo> if different from <external_name>
  3. Push your branch to the external's repo, in preparation of merging following their workflow: (git push <external_repo> <external_branchname>)
  4. Follow other procedures for updating the external (depending on that external's workflow).

Note that Steps 3+ may be different depending on the rules for updating the external. To simply share the split code, push <external_branchname> to the appropriate remote repository.

Related articles

Filter by label

There are no items with the selected labels at this time.