For example, you can do a git remote --verbose
and git will show all the remotes you have on your project, git branch
will show all the branches and signal the current branch, but how to list all subtrees, without any destructive command? git subtree
will give the usage examples, but won't list anything. subtree only have add
,pull
,push
,split
,merge
.

- 17,795
- 22
- 77
- 119

- 6,860
- 6
- 56
- 88
-
1Excuse me but what is a subtree? Running `git subtree` gave me `git: 'subtree' is not a git command.` . – Jokester May 20 '13 at 01:35
-
1you need to install subtree apart, it's not bundled with git right now. http://engineeredweb.com/blog/how-to-install-git-subtree/ . subtree is a much better alternative to submodules :) – pocesar May 20 '13 at 03:07
-
1@pocesar git subtree [has been merged](https://github.com/apenwarr/git-subtree/blob/master/THIS-REPO-IS-OBSOLETE) to the mainline git, and it's been available since version 1.7.11 – 1615903 May 20 '13 at 05:10
-
indeed, but some git versions (like from @jokester above) didn't come with it. I'm using msysgit 1.8.2.1 on windows, and it comes with it :) – pocesar May 20 '13 at 15:04
-
Hmmm... I just built 1.8.4 from source to get the latest, and it also says 'subtree' is not a git command. My "git --version' says: git version 1.8.4.rc1.4.gd6cbf2f – Stabledog Aug 05 '13 at 18:18
-
Mystery solved: it's not enough to build git, you also have to build contrib/subtree (there's an INSTALL file there). Otherwise, even the latest git will complain that 'subtree' is not a meaningful command. – Stabledog Aug 05 '13 at 18:30
4 Answers
There isn't any explicit way to do that (at least, for now), the only available commands are listed here (as you noted yourself, but here's a reference for future seekers): https://github.com/git/git/blob/master/contrib/subtree/git-subtree.txt
I went through the code (basically all this mechanism is a big shell script file), all of the tracking is done through commit messages, so all the functions use git log
mechanism with lots of grep
-ing to locate it's own data.
Since subtree must have a folder with the same name in the root folder of the repository, you can run this to get the info you want (in Bash shell):
git log | grep git-subtree-dir | tr -d ' ' | cut -d ":" -f2 | sort | uniq
Now, this doesn't check whether the folder exist or not (you may delete it and the subtree mechanism won't know), so here's how you can list only the existing subtrees, this will work in any folder in the repository:
git log | grep git-subtree-dir | tr -d ' ' | cut -d ":" -f2 | sort | uniq | xargs -I {} bash -c 'if [ -d $(git rev-parse --show-toplevel)/{} ] ; then echo {}; fi'
If you're really up to it, propose it to Git guys to include in next versions:)

- 1,130
- 10
- 21
-
1the command you give doesn't work for me. git log | grep git-subtree-dir doesn't return any results (git version 1.7.9.5) – FlipMcF Sep 06 '13 at 00:34
-
3+1. @procesar, FlipMcF: This is worked for me in "git bash" on Windows: "git version 1.8.5.2.msysgit.0". The reason it should work is that "git subtree" command adds several lines starting with "git-subtree-" to the commit message and one of the lines looks like "git-subtree-dir:you-prefix-folder". For the "prof" - just look at the output of "git log" right after you run "git subtree add ..." and you'll see those lines. – Eddy Shterenberg Jan 08 '14 at 02:29
-
1@FlipMcF, official subtree support was added in 1.7.11, so I guess you're using an old and detached subtree module, which doesn't work as modern versions. You can either install the most updated subtree script (see [here](http://log.pardus.de/2012/08/modular-git-with-git-subtree.html)), or upgrade your whole git installation. – Sagi Iltus Jan 14 '14 at 14:31
-
Thanks! This is why I made sure to include my version in my comment. I had a hunch it was because of my old version. – FlipMcF Jan 17 '14 at 22:27
-
-
https://stackoverflow.com/questions/16641057/how-can-i-list-the-git-subtrees-on-the-root#comment80569427_27298572 – smarber Nov 13 '17 at 10:55
-
`git subtree` is official. It has also some Cons... That's why `git vendor` has been invented https://manpages.debian.org/testing/git-man/git-subtree.1.en.html https://github.com/brettlangdon/git-vendor – Sandburg Jan 08 '20 at 09:46
-
`git subtree` is not "official" as long as its in the `contrib` directory of the Git source code... – philb Jul 22 '21 at 21:06
-
1A more robust version would be `git log --format=%b | awk '/git-subtree-dir/{ print $NF }' | sort --unique`, in case `git config core.format`[`.pretty`] is set to display without the commit message `%b`ody. – Daniel Bayley Jan 27 '23 at 14:03
-
Building on the other solutions, here is an even more robust solution (handles if you have your log format reconfigured and also whitespace in your folder names): `git log --format=%b | grep -oP 'git-subtree-dir:\s*\K.*'` – neingeist Aug 12 '23 at 13:43
Following up on Sagi Illtus' answer, add the following alias to your ~/.gitconfig
[alias]
ls-subtrees = !"git log | grep git-subtree-dir | awk '{ print $2 }'"
Then you can git ls-subtrees
from the root of your repository to show all subtree paths:
$> cd /path/to/repository
$> git ls-subtrees
some/subtree/dir

- 1
- 1

- 10,034
- 2
- 41
- 60
-
This would be great except it spits out duplicates in my repo - likely because I've added deleted and re-added a subtree. When I actually know what I'm doing this will be helpful ;-) – Jul 30 '15 at 14:40
-
2@MattBracewell Have a look at `uniq`. You can update the alias to pipe to it, or `git ls-subtrees|uniq` – kenchilada Feb 16 '17 at 02:36
-
4Or use `sort -u` and have the directories in alphabetical order as a bonus! – Potherca Oct 18 '17 at 13:21
-
No need for the call to `grep`: `[alias] subtree-list = !git log --format=%b | awk '/git-subtree-dir/{ print $NF }' | sort --unique` – Daniel Bayley Jan 27 '23 at 14:01
The problem with grepping the log is this tells you nothing about whether the subtree still exists or not. I've worked around this by simply testing the existence of the directory:
[alias]
ls-subtrees = !"for i in $(git log | grep git-subtree-dir | sed -e 's/^.*: //g' | uniq); do test -d $i && echo $i; done"

- 459
- 6
- 9