The bot in the #git
channel on freenode holds links to recommended reading.
A couple of these were invoked in the last week or so not long before I
wandered into the channel (via Esc A in irssi) so I was able to notice them.
One of them is a book, Git in The Trenches. I figured I'd take a quick look, mostly to see how useful the book is for my purposes (about which later).
One thing that caught my eye is that the introductory material includes the claim that the book covers the top 21 or 21 most important or 21 most useful--at least, in some way, makes some kind of claim about 21 superlative git commands, the exact phrasing of which I could go back and look for and quote precisely. But that's not my point. My point is that the number 21 stuck in my head.
It stuck in my head because in several aspects of my relationship with git--as a user, as a learner, as an educator--I am interested in the git learning curve and the order in which someone might learn to use the many git subcommands.
So, I pulled down the source for the book and quickly put together a one-liner that gave me a ranked list of the occurrences of the different subcommands from examples in the book. Its not necessarily comprehensive since it probably doesn't capture every mention of any given subcommand, but I expect it's not far off, either:
gitt$ grep -h "\$ git " *tex | awk '{print $3}' | sort | uniq -c | sort -nr | nl
1 40 checkout
2 39 commit
3 29 branch
4 25 log
5 19 diff
6 17 status
7 16 add
8 11 remote
9 11 cat-file
10 9 reset
11 9 bisect
12 8 merge
13 7 stash
14 7 logg
15 6 show
16 6 clone
17 5 tag
18 5 submodule
19 5 rm
20 5 fetch
21 4 rebase
22 3 push
23 3 pull
24 3 daemon
25 2 instaweb
26 2 init
27 2 grep
28 2 filter-branch
29 2 config
30 2 am
31 1 rev-parse
32 1 reflog
33 1 mv
34 1 merge-base
35 1 format-patch
36 1 bundle
37 1 apply
Clearly there are some of the more obscure commands that get used a lot in examples here, such that the count here is not indicative of the top N for whatever cutoff of N one wants to use.
The logg
subcommand is an alias he uses as an example for defining and
using aliases.
Aside from that, I might pull out the following list as git essentials:
checkout
commit
branch
log
diff
status
add
remote
merge
stash
show
clone
rm
fetch
rebase
push
pull
init
mv
reset
config
The remaining commands are specialized enough that one could give a pretty good introduction, sufficient to get someone productively started using git, while deferring much, if any use or discussion of them:
tag
submodule
daemon
instaweb
grep
filter-branch
am
rev-parse
reflog
merge-base
format-patch
bundle
apply
bisect
cat-file
This made me wonder how many git subcommands there are. Or, at least, how
many are installed on my system with their own man
pages, so I wrote a
one-liner to sort that out:
dpkg -l | grep " git"
dpkg -L git-man | grep "git-" | nl
1 /usr/share/man/man1/git-daemon.1.gz
2 /usr/share/man/man1/git-submodule.1.gz
3 /usr/share/man/man1/git-checkout.1.gz
4 /usr/share/man/man1/git-mailinfo.1.gz
5 /usr/share/man/man1/git-diff-tree.1.gz
6 /usr/share/man/man1/git-unpack-objects.1.gz
7 /usr/share/man/man1/git-fsck-objects.1.gz
8 /usr/share/man/man1/git-verify-tag.1.gz
9 /usr/share/man/man1/git-remote-testgit.1.gz
10 /usr/share/man/man1/git-merge-base.1.gz
11 /usr/share/man/man1/git-show-ref.1.gz
12 /usr/share/man/man1/git-for-each-ref.1.gz
13 /usr/share/man/man1/git-difftool.1.gz
14 /usr/share/man/man1/git-cherry-pick.1.gz
15 /usr/share/man/man1/git-unpack-file.1.gz
16 /usr/share/man/man1/git-imap-send.1.gz
17 /usr/share/man/man1/git-notes.1.gz
18 /usr/share/man/man1/git-shell.1.gz
19 /usr/share/man/man1/git-parse-remote.1.gz
20 /usr/share/man/man1/git-revert.1.gz
21 /usr/share/man/man1/git-merge-file.1.gz
22 /usr/share/man/man1/git-mergetool.1.gz
23 /usr/share/man/man1/git-diff-files.1.gz
24 /usr/share/man/man1/git-fast-export.1.gz
25 /usr/share/man/man1/git-hash-object.1.gz
26 /usr/share/man/man1/git-symbolic-ref.1.gz
27 /usr/share/man/man1/git-sh-i18n--envsubst.1.gz
28 /usr/share/man/man1/git-apply.1.gz
29 /usr/share/man/man1/git-repack.1.gz
30 /usr/share/man/man1/git-receive-pack.1.gz
31 /usr/share/man/man1/git-mergetool--lib.1.gz
32 /usr/share/man/man1/git-gc.1.gz
33 /usr/share/man/man1/git-rm.1.gz
34 /usr/share/man/man1/git-rev-list.1.gz
35 /usr/share/man/man1/git-merge.1.gz
36 /usr/share/man/man1/git-index-pack.1.gz
37 /usr/share/man/man1/git-init.1.gz
38 /usr/share/man/man1/git-get-tar-commit-id.1.gz
39 /usr/share/man/man1/git-verify-pack.1.gz
40 /usr/share/man/man1/git-merge-index.1.gz
41 /usr/share/man/man1/git-pack-refs.1.gz
42 /usr/share/man/man1/git-pack-objects.1.gz
43 /usr/share/man/man1/git-credential.1.gz
44 /usr/share/man/man1/git-pack-redundant.1.gz
45 /usr/share/man/man1/git-add.1.gz
46 /usr/share/man/man1/git-remote-ext.1.gz
47 /usr/share/man/man1/git-checkout-index.1.gz
48 /usr/share/man/man1/git-name-rev.1.gz
49 /usr/share/man/man1/git-whatchanged.1.gz
50 /usr/share/man/man1/git-help.1.gz
51 /usr/share/man/man1/git-patch-id.1.gz
52 /usr/share/man/man1/git-ls-files.1.gz
53 /usr/share/man/man1/git-check-ignore.1.gz
54 /usr/share/man/man1/git-stash.1.gz
55 /usr/share/man/man1/git-ls-remote.1.gz
56 /usr/share/man/man1/git-relink.1.gz
57 /usr/share/man/man1/git-remote-fd.1.gz
58 /usr/share/man/man1/git-diff.1.gz
59 /usr/share/man/man1/git-archive.1.gz
60 /usr/share/man/man1/git-count-objects.1.gz
61 /usr/share/man/man1/git-http-push.1.gz
62 /usr/share/man/man1/git-interpret-trailers.1.gz
63 /usr/share/man/man1/git-clone.1.gz
64 /usr/share/man/man1/git-stage.1.gz
65 /usr/share/man/man1/git-check-attr.1.gz
66 /usr/share/man/man1/git-http-backend.1.gz
67 /usr/share/man/man1/git-upload-pack.1.gz
68 /usr/share/man/man1/git-mktag.1.gz
69 /usr/share/man/man1/git-update-server-info.1.gz
70 /usr/share/man/man1/git-credential-cache.1.gz
71 /usr/share/man/man1/git-ls-tree.1.gz
72 /usr/share/man/man1/git-filter-branch.1.gz
73 /usr/share/man/man1/git-clean.1.gz
74 /usr/share/man/man1/git-check-ref-format.1.gz
75 /usr/share/man/man1/git-mktree.1.gz
76 /usr/share/man/man1/git-reflog.1.gz
77 /usr/share/man/man1/git-diff-index.1.gz
78 /usr/share/man/man1/git-upload-archive.1.gz
79 /usr/share/man/man1/git-instaweb.1.gz
80 /usr/share/man/man1/git-var.1.gz
81 /usr/share/man/man1/git-send-pack.1.gz
82 /usr/share/man/man1/git-show-index.1.gz
83 /usr/share/man/man1/git-cat-file.1.gz
84 /usr/share/man/man1/git-check-mailmap.1.gz
85 /usr/share/man/man1/git-column.1.gz
86 /usr/share/man/man1/git-quiltimport.1.gz
87 /usr/share/man/man1/git-sh-setup.1.gz
88 /usr/share/man/man1/git-init-db.1.gz
89 /usr/share/man/man1/git-prune.1.gz
90 /usr/share/man/man1/git-fetch-pack.1.gz
91 /usr/share/man/man1/git-prune-packed.1.gz
92 /usr/share/man/man1/git-stripspace.1.gz
93 /usr/share/man/man1/git-rebase.1.gz
94 /usr/share/man/man1/git-update-ref.1.gz
95 /usr/share/man/man1/git-update-index.1.gz
96 /usr/share/man/man1/git-log.1.gz
97 /usr/share/man/man1/git-verify-commit.1.gz
98 /usr/share/man/man1/git-status.1.gz
99 /usr/share/man/man1/git-fetch.1.gz
100 /usr/share/man/man1/git-merge-tree.1.gz
101 /usr/share/man/man1/git-pull.1.gz
102 /usr/share/man/man1/git-request-pull.1.gz
103 /usr/share/man/man1/git-mv.1.gz
104 /usr/share/man/man1/git-push.1.gz
105 /usr/share/man/man1/git-merge-one-file.1.gz
106 /usr/share/man/man1/git-cherry.1.gz
107 /usr/share/man/man1/git-describe.1.gz
108 /usr/share/man/man1/git-worktree.1.gz
109 /usr/share/man/man1/git-rerere.1.gz
110 /usr/share/man/man1/git-tag.1.gz
111 /usr/share/man/man1/git-commit-tree.1.gz
112 /usr/share/man/man1/git-credential-cache--daemon.1.gz
113 /usr/share/man/man1/git-remote.1.gz
114 /usr/share/man/man1/git-annotate.1.gz
115 /usr/share/man/man1/git-http-fetch.1.gz
116 /usr/share/man/man1/git-mailsplit.1.gz
117 /usr/share/man/man1/git-commit.1.gz
118 /usr/share/man/man1/git-fast-import.1.gz
119 /usr/share/man/man1/git-show.1.gz
120 /usr/share/man/man1/git-am.1.gz
121 /usr/share/man/man1/git-write-tree.1.gz
122 /usr/share/man/man1/git-fsck.1.gz
123 /usr/share/man/man1/git-bisect.1.gz
124 /usr/share/man/man1/git-read-tree.1.gz
125 /usr/share/man/man1/git-branch.1.gz
126 /usr/share/man/man1/git-sh-i18n.1.gz
127 /usr/share/man/man1/git-replace.1.gz
128 /usr/share/man/man1/git-reset.1.gz
129 /usr/share/man/man1/git-credential-store.1.gz
130 /usr/share/man/man1/git-grep.1.gz
131 /usr/share/man/man1/git-bundle.1.gz
132 /usr/share/man/man1/git-blame.1.gz
133 /usr/share/man/man1/git-rev-parse.1.gz
134 /usr/share/man/man1/git-config.1.gz
135 /usr/share/man/man1/git-subtree.1.gz
136 /usr/share/man/man1/git-fmt-merge-msg.1.gz
137 /usr/share/man/man1/git-shortlog.1.gz
138 /usr/share/man/man1/git-show-branch.1.gz
139 /usr/share/man/man1/git-web--browse.1.gz
140 /usr/share/man/man1/git-format-patch.1.gz
141 /usr/share/doc/git-man
142 /usr/share/doc/git-man/changelog.Debian.gz
143 /usr/share/doc/git-man/copyright
Further commentary about the relative merits of different ways of learning
and teaching git
probably should happen in another post (rant). Even so,
I figure I should mention briefly that my own approach has been an initial
focus on the bare minimum, tracking changes locally without any interaction,
at first, with a remote or even working with branches.
To that end, my bare minimum list is something like
git init
git add
git commit
In a second iteration, I add the query tools:
git status
git log
before moving on from there.
Pulling out the subcommand name from those gives, more or less, the following:
(the last two entries are not subcommands, but whatever)
dpkg -L git-man | grep "git-" | tr '/ .' ' ' | awk '{print $5}' | sed 's@git-@@' | nl
1 daemon
2 submodule
3 checkout
4 mailinfo
5 diff-tree
6 unpack-objects
7 fsck-objects
8 verify-tag
9 remote-testgit
10 merge-base
11 show-ref
12 for-each-ref
13 difftool
14 cherry-pick
15 unpack-file
16 imap-send
17 notes
18 shell
19 parse-remote
20 revert
21 merge-file
22 mergetool
23 diff-files
24 fast-export
25 hash-object
26 symbolic-ref
27 sh-i18n--envsubst
28 apply
29 repack
30 receive-pack
31 mergetool--lib
32 gc
33 rm
34 rev-list
35 merge
36 index-pack
37 init
38 get-tar-commit-id
39 verify-pack
40 merge-index
41 pack-refs
42 pack-objects
43 credential
44 pack-redundant
45 add
46 remote-ext
47 checkout-index
48 name-rev
49 whatchanged
50 help
51 patch-id
52 ls-files
53 check-ignore
54 stash
55 ls-remote
56 relink
57 remote-fd
58 diff
59 archive
60 count-objects
61 http-push
62 interpret-trailers
63 clone
64 stage
65 check-attr
66 http-backend
67 upload-pack
68 mktag
69 update-server-info
70 credential-cache
71 ls-tree
72 filter-branch
73 clean
74 check-ref-format
75 mktree
76 reflog
77 diff-index
78 upload-archive
79 instaweb
80 var
81 send-pack
82 show-index
83 cat-file
84 check-mailmap
85 column
86 quiltimport
87 sh-setup
88 init-db
89 prune
90 fetch-pack
91 prune-packed
92 stripspace
93 rebase
94 update-ref
95 update-index
96 log
97 verify-commit
98 status
99 fetch
100 merge-tree
101 pull
102 request-pull
103 mv
104 push
105 merge-one-file
106 cherry
107 describe
108 worktree
109 rerere
110 tag
111 commit-tree
112 credential-cache--daemon
113 remote
114 annotate
115 http-fetch
116 mailsplit
117 commit
118 fast-import
119 show
120 am
121 write-tree
122 fsck
123 bisect
124 read-tree
125 branch
126 sh-i18n
127 replace
128 reset
129 credential-store
130 grep
131 bundle
132 blame
133 rev-parse
134 config
135 subtree
136 fmt-merge-msg
137 shortlog
138 show-branch
139 web--browse
140 format-patch
141 changelog
142 copyright