> For the complete documentation index, see [llms.txt](https://bryan-guner.gitbook.io/my-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bryan-guner.gitbook.io/my-docs/lambda-labs/background-information/background-info/github.md).

# GITHUB:

![Illustration of git branch](https://wac-cdn.atlassian.com/dam/jcr:8e57216e-269e-49e6-aff2-5c03b8512e73/hero.svg?cdnVersion=1826)

## Git subtree: the alternative to Git submodule

***

The Internet is full of articles on why you shouldn’t use Git submodules. While submodules are useful for a few use cases, they do have several drawbacks.

Are there alternatives? The answer is: yes! There are (at least) two tools that can help track the history of software dependencies in your project while allowing you to keep using Git:

* `git subtree`
* Google repo

In this post we will look at `git subtree` and show why it is an improvement – albeit not perfect – over git submodule.

### What is `git subtree`, and why should I use it?

`git subtree` lets you nest one repository inside another as a sub-directory. It is one of several ways Git projects can manage project dependencies.![A diagram showing the interaction between two repositories before and after using Git Subtree.](https://wac-cdn.atlassian.com/dam/jcr:f5fcef58-5b93-4ff4-b9a1-3f721d29ead8/BeforeAfterGitSubtreeDiagram.png?cdnVersion=1826)

Why you may want to consider `git subtree`

* Management of a simple workflow is easy.
* Older version of Git are supported (even older than v1.5.2).
* The sub-project’s code is available right after the clone of the super project is done.
* `git subtree` does not require users of your repository to learn anything new. They can ignore the fact that you are using `git subtree` to manage dependencies.
* `git subtree` does not add new metadata files like git submodule does (i.e., .gitmodule).
* Contents of the module can be modified without having a separate repository copy of the dependency somewhere else.

Drawbacks (but in our opinion they're largely acceptable):

* You must learn about a new merge strategy (i.e.`git subtree`).
* Contributing code back upstream for the sub-projects is slightly more complicated.
* The responsibility of not mixing super and sub-project code in commits lies with you.

### How to use `git subtree`

`git subtree` is available in stock version of Git since May 2012 – v1.7.11 and above. The version installed by homebrew on OSX already has subtree properly wired, but on some platforms you might need to follow the installation instructions.

Here is a canonical example of tracking a vim plug-in using `git subtree.`

#### The quick and dirty way without remote tracking

If you just want a couple of one-liners to cut and paste, read this paragraph. First add `git subtree` at a specified prefix folder:

```
 git subtree add --prefix .vim/bundle/tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.git main --squash
```

(The common practice is to not store the entire history of the subproject in your main repository, but If you want to preserve it just omit the *–squash* flag.)

The above command produces this output:

```
git fetch https://bitbucket.org/vim-plugins-mirror/vim-surround.git main
warning: no common commits
remote: Counting objects: 338, done.
remote: Compressing objects: 100% (145/145), done.
remote: Total 338 (delta 101), reused 323 (delta 89)
Receiving objects: 100% (338/338), 71.46 KiB, done.
Resolving deltas: 100% (101/101), done.
From https://bitbucket.org/vim-plugins-mirror/vim-surround.git
* branch main -} FETCH_HEAD
Added dir '.vim/bundle/tpope-vim-surround'
```

As you can see this records a merge commit by squashing the whole history of the vim-surround repository into a single one:

```
1bda0bd [3 minutes ago] (HEAD, stree) Merge commit 'ca1f4da9f0b93346bba9a430c889a95f75dc0a83' as '.vim/bundle/tpope-vim-surround' [Nicola Paolucci]
ca1f4da [3 minutes ago] Squashed '.vim/bundle/tpope-vim-surround/' content from commit 02199ea [Nicola Paolucci]
```

If after a while you want to update the code of the plugin from the upstream repository you can just do a `git subtree` pull:

```
git subtree pull --prefix .vim/bundle/tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.git main --squash
```

This is very quick and painless, but the commands are slightly lengthy and hard to remember. We can make the commands shorter by adding the sub-project as a remote.

#### Adding the sub-project as a remote

Adding the subtree as a remote allows us to refer to it in shorter form:

```
git remote add -f tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.git
```

Now we can add the subtree (as before), but now we can refer to the remote in short form:

```
git subtree add --prefix .vim/bundle/tpope-vim-surround tpope-vim-surround main --squash
```

The command to update the sub-project at a later date becomes:

```
git fetch tpope-vim-surround main
git subtree pull --prefix .vim/bundle/tpope-vim-surround tpope-vim-surround main --squash
```

#### Contributing back upstream

We can freely commit our fixes to the sub-project in our local working directory now. When it’s time to contribute back to the upstream project, we need to fork the project and add it as another remote:

```
git remote add durdn-vim-surround ssh://git@bitbucket.org/durdn/vim-surround.git
```

Now we can use the *subtree push* command like the following:

```
git subtree push --prefix=.vim/bundle/tpope-vim-surround/ durdn-vim-surround main
git push using: durdn-vim-surround main
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 308 bytes, done.
Total 3 (delta 2), reused 0 (delta 0)
To ssh://git@bitbucket.org/durdn/vim-surround.git
02199ea..dcacd4b dcacd4b21fe51c9b5824370b3b224c440b3470cb -} main
```

After this we’re ready and we can open a pull-request to the maintainer of the package.

#### Can I do this without using the `git subtree` command?

Yes! Yes you can. `git subtree` is different from the subtree merge strategy. You can still use the merge strategy even if for some reason `git subtree` is not available. Here is how you would go about it.

Add the dependency as a simple `git remote`:

```
git remote add -f tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.git
```

Before reading the contents of the dependency into the repository, it’s important to record a merge so that we can track the entire tree history of the plug-in up to this point:

```
git merge -s ours --no-commit tpope-vim-surround/main
```

Which outputs:

```
Automatic merge went well; stopped before committing as requested
```

We then read the content of the latest tree-object into the plugin repository into our working directory ready to be committed:

```
git read-tree --prefix=.vim/bundle/tpope-vim-surround/ -u tpope-vim-surround/main
```

Now we can commit (and it will be a merge commit that will preserve the history of the tree we read):

```
git ci -m"[subtree] adding tpope-vim-surround"
[stree 779b094] [subtree] adding tpope-vim-surround
```

When we want to update the project we can now pull using the `git subtree` merge strategy:

```
git pull -s subtree tpope-vim-surround main
```

### `Git subtree` is a great alternative

After having used git submodules for a while, you'll see `git subtree` solves lots of the problems with git submodule. As usual, with all things Git, there is a learning curve to make the most of the feature.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://bryan-guner.gitbook.io/my-docs/lambda-labs/background-information/background-info/github.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
