3 Git is a distributed vesioning control system.
9 *** DONE [[http://importantshock.wordpress.com/2008/08/07/git-vs-mercurial/][Git vs. Mercurial blog entry: MacGyver vs. Bond]]
10 CLOSED: [2008-08-28 Thu 05:06]
11 - State "DONE" [2008-08-28 Thu 05:06]
12 - State "TODO" [2008-08-28 Thu 05:06]
14 A nice, touchy-feely intro to the difference between Git and
15 Mercurial. Despite the one-stop-shopping-appeal of Mercurial, I will
16 go with my command-line-linux-philosophy-loving, blogs-with-ikiwiki
17 heart and head into git-land.
21 *** TODO [[http://rubinius.lighthouseapp.com/projects/5089/using-git][Rubinius git page]] Get going fast
22 - State "TODO" [2008-08-28 Thu 05:06]
24 *** TODO [[http://www.kernel.org/pub/software/scm/git/docs/gittutorial.html][gittutorial]] The official intro ;), looks fairly readable…
25 - State "TODO" [2008-08-28 Thu 05:11]
27 *** TODO [[http://www.kernel.org/pub/software/scm/git/docs/everyday.html][Everyday GIT With 20 Commands Or So]] Nicely broken down by goal
28 - State "TODO" [2008-08-28 Thu 05:06]
30 *** TODO [[http://book.git-scm.com/][Git Community Book]] Open source wiki/howto website
34 - State "TODO" [2008-08-28 Thu 05:06]
38 *** TODO [[http://newartisans.com/blog_files/diving.into.git.php][Diving into git blog entry]] Importing the Subversion history
39 - State "TODO" [2008-08-28 Thu 05:06]
41 *** TODO [[http://git.or.cz/course/svn.html][Git - SVN Crash Course]] ?
42 - State "TODO" [2008-08-28 Thu 05:06]
44 *** TODO [[http://utsl.gen.nz/talks/git-svn/intro.html][An introduction to git-svn for Subversion/SVK users and deserters]]
45 - State "TODO" [2008-08-28 Thu 06:09]
47 Lots of political digression, but also lots of useful info. Your call.
49 ** Enforcing development policies
51 *** TODO [[http://www.kernel.org/pub/software/scm/git/docs/howto/update-hook-example.txt][Push hooks]]
52 - State "TODO" [2008-08-28 Thu 05:16]
56 *** DONE [[http://blog.offbytwo.com/2008/04/16/running-nosetests-as-a-git-pre-commit-hook/][Pre commit hooks]]
57 CLOSED: [2008-09-02 Tue 08:48]
58 - State "DONE" [2008-09-02 Tue 08:48]
59 - State "TODO" [2008-09-02 Tue 08:46]
61 Basically, put whatever you want in =.git/hooks/pre-commit=.
64 : ./.git/hooks/pre-commit-make-check || exit 1
66 right after the initial comments with
68 : $ cat .git/hooks/pre-commit-make-check
71 Don't forget to =chmod 744= both scripts to make them executible.
72 Also note that these scripts are run from the base repo directory,
73 which is why I had to include the relative path to
74 =pre-commit-make-check=, and didn't need =cd ../../= in the check
77 *** DONE [[http://changelog.complete.org/posts/586-Rebase-Considered-Harmful.html][Rebase Considered Harmful]]
78 CLOSED: [2008-08-28 Thu 05:27]
79 - State "DONE" [2008-08-28 Thu 05:27]
80 - State "TODO" [2008-08-28 Thu 05:18]
82 A “keep the warts” vs. “stay true to history” monologue. Advocates
83 against rebasing public repos because (quotes from the git-rebase
86 "When you rebase a branch, you are changing its history in a way
87 that will cause problems for anyone who already has a copy of
88 the branch in their repository and tries to pull updates from
91 Personally, I feel like a middle ground, where private mini-branches
92 get a little constructive history tweaking is a good thing. Noone
93 cares about typos in comments, and it adds noise to the development
94 signal, so fix those commits in your private branch. Once you go
95 public though, don't mess with the history, since it would be even
96 more confusing to have conflicting histories in seperate public
97 repositories. Anything serious enough to require a altering the
98 author field should probably not be changed.
100 My thoughts are shared by others, for example commenter #7 Jing Xue.
101 However, commenter #8 links to [[http://www.reddit.com/r/programming/comments/6ube0/synchronizing_development_rebase_vs_pullmerge_git/?sort=top][Synchronizing development: rebase
102 vs. pull+merge, GIT vs. Mercurial]], where oddbod points out that the
103 real problem when “mid-level”, public repos rebase to avoid sending
104 known-bugged patches upstream. He says they avoid the obviously
105 better solution of sending up the bad patch with a patch-patch hard on
106 its heels, which would avoid rebasing a public repo, and still
107 preserve the spirit and authorship of the changes.
109 **** Aside: rebase etymology
111 I just realized that “rebasing” is attaching your branch to a
112 different base point on the tree. Afterward, it looks like you made
113 all of your adjustments right now, not in parallel with a bunch of
114 other fixes on the main branch.
116 ** Setting a description for your repo
118 Edit =.git/description=.
122 http://www.kernel.org/pub/software/scm/git/docs/git-notes.html
123 http://git-scm.com/2010/08/25/notes.html
124 http://alblue.bandlem.com/2011/11/git-tip-of-week-git-notes.html
130 People are indeed working on [[http://gittorrent.utsl.gen.nz/rfc.html][the obvious protocol]].
132 ** The git-* to git * transition
134 The transition occured between git 1.5.4 and 1.6.0. See the [[http://www.kernel.org/pub/software/scm/git/docs/RelNotes-1.6.0.txt][1.6.0
135 release notes]] for details.
139 ** Gitting =chem_web=, my first git project
141 *** Repository creation and setup
142 From the [[#git-book][Git Community Book]].
146 : $ apt-get install git-core gitk
149 From the [[http://book.git-scm.com/2_setup_and_initialization.html][Git Community Book]].
151 By default that file is =~/.gitconfig= and the contents will then look like this:
154 : name = W. Trevor King
155 : email = wking at drexel dot edu
157 *** Initialize repository
158 From the [[http://book.git-scm.com/3_getting_a_git_repository.html][Git Community Book]].
160 : $ cd ~/rsrch/chem_web
163 *** Add some files to the repository
164 From the [[http://book.git-scm.com/3_normal_workflow.html][Git Community Book]].
166 : $ git add README *.py docs templates
169 Oops, =git add= adds all of a directory's contents too. Remove some
170 of the automatically generated files. =git rm= removes a file from
171 both the working directory and the index. I wish I could just remove
172 from the index, but I'm not sure how yet. Ah well, the reason I want
173 to remove them is that they are automatically generated ;).
175 : $ git rm -f docs/*.pdf
178 a bunch of other work while I clean up the mess I've made. Keep going
179 until =git status= looks right.
181 *** Commit the code to the master branch
182 From the [[http://book.git-scm.com/3_normal_workflow.html][Git Community Book]].
186 Or you can automatically add any changed tracked-files with
190 *** Creating the development branch
191 From the [[http://book.git-scm.com/3_basic_branching_and_merging.html][Git Community Book]].
193 My workflow will be in two branches:
195 * =master=, the current stable/working release
196 * =dev=, the feature development branch
198 I will develop new code in =dev= until I am happy with its
199 performance, and then merge back into the master branch. Old bugs
200 will be fixed in the master branch, and then cherry-picked into the
201 dev branch. That's the current plan anyway ;). Create the =dev=
206 *** Changing branches and coding
207 From the [[http://book.git-scm.com/3_basic_branching_and_merging.html][Git Community Book]].
217 Now add that cool new feature, NFPA diamonds for the cabinets :p.
218 When you feel it is appropriate, commit your changes in the local
223 *** Correcting private commit mistakes
224 From the [[http://book.git-scm.com/4_undoing_in_git_-_reset%2C_checkout_and_revert.html][Git Community Book]].
226 Oops, I forgot X or made a typo in my commit message. My =dev= branch
227 is not public, so go ahead and fix the mistake. Then run
229 : $ git commit --amend
231 This may leave some danglers
234 : dangling blob 03cabac5fa426ca8df4dff1fdb2596b68d2f4c5a
235 : dangling blob 87488a0b4ea976127d6b9171ef6f10941a1dd74e
238 which you can clean up with
242 *** Bring the master branch up to speed
243 From the [[http://book.git-scm.com/3_basic_branching_and_merging.html][Git Community Book]].
245 : $ git checkout master
248 You may have to deal with a [[#conflicting-merge][conflicting merge]].
251 From the [[http://book.git-scm.com/3_basic_branching_and_merging.html][Git Community Book]].
253 : $ git branch -d dev
255 The =-d= ensures the changes have already been merged back into the
256 current branch. If you want to kill the brach without merging use
258 : $ git branch -D dev
260 *** Repository maitenance
261 From the [[http://book.git-scm.com/4_maintaining_git.html][Git Community Book]].
263 Recompress (to keep the compression most effective)
267 Check repository consitency
271 Both should be run manually from time to time.
273 *** Working over a network
274 From the [[http://book.git-scm.com/3_distributed_workflows.html][Git Community Book]].
276 **** Grab a remote repository
278 A remote friend wants to work on your code, or more likely, you're at
279 home and you want to work on your code at work. Grab the repo using
282 : $ git clone ssh://wking@loki/~/rsrch/chem_inventory ci
286 : ssh://[user@]host.xz/~/path/to/repo.git
288 git URL notation listed in =man git-clone=.
290 **** Possibly remove the reference to the remote repository
292 If you're decomissioning the remote repository, you can remove it from
295 : $ git remote rm <name>
297 **** Work on the repository
299 Nothing changes here.
301 **** Get your remote partner to pull your changes back upstream
303 : $ git remote add bob /home/bob/repo
305 : $ git log -p dev remotes/bob/master
306 : $ git merge remotes/bob/master
310 : $ git remote rm bob
312 ** Gitting sawsim, migration from svn
316 : $ apt-get install git-core git-svn gitk
318 *** Repository migration from svn
320 :CUSTOM_ID: svn-migration
323 Following [[http://github.com/maddox][Jon Maddox]] at the [[http://www.simplisticcomplexity.com/2008/03/05/cleanly-migrate-your-subversion-repository-to-a-git-repository/][Simplistic Complexity blog]].
325 **** Create the decoy directory
327 =git svn= keeps some info about the svn repository, to make it easier
328 to keep the two in sync. However we are not interested in staying in
329 sync, we just want to move to Git. Create a decoy Git version of the
334 : $ git svn init svn://abax.physics.drexel.edu/sawsim/trunk/
335 : $ cat >> .git/config <<EOF
337 : authorsfile = users.txt
339 : $ cat > users.txt <<EOF
340 : wking = W. Trevor King <wking at drexel dot edu>
344 Jon Maddox suggests using
346 : $ git config svn.authorsfile ~/Desktop/users.txt
348 instead of my manual =.git/config= editing, but my stock Debian git
349 (1.4.4.4) doesn't seem to have =git config=. No big deal.
351 Check that this worked and translated your users correctly with
355 ***** Warning: here documents
357 Some shells might not like my [[http://tldp.org/LDP/abs/html/here-docs.html][here document]] Bash syntax. In that
358 case, write the files another way.
360 **** Create the clean directory
362 When we clone the decoy directory, all the svn junk gets left behind.
364 First, leave the sawsim.svn directory
368 and clone like you normally would
370 : $ git clone sawsim.svn sawsim
372 You don't need the =[svn]= stuff in =.git/config= anymore either.
373 I don't remember if they came over on their own or not…
375 I removed the origin information with
377 : $ rm .git/remotes/origin
379 Although a better approach would probably be
381 : $ git remote rm origin
388 The sawsim code is mostly in a single [[http://www.cs.tufts.edu/~nr/noweb/][noweb]] file. Extracting all the
389 source from the file creates lot of indirectly versioned clutter. To
390 avoid having all your =git status= calls swamped with untracked files,
391 Just add the filenames (globbing allowed) to =.gitignore=.
396 *** Making your repository public/Publishing your repository
397 From the [[http://book.git-scm.com/4_setting_up_a_public_repository.html][Git Community Book]]
399 To distribute your repo via HTTP (easier on someone else's server).
401 : user@devel$ ssh server
402 : server$ cd ~/public_html
403 : server$ git clone --bare ssh://user@devel/~/path/to/repo.git repo.git
404 : server$ cd repo.git
405 : server$ touch git-daemon-export-ok
406 : server$ git --bare update-server-info
407 : server$ chmod a+x hooks/post-update
409 Others can clone or pull from your URL with
411 : anon$ git clone http://server/~you/repo.git
413 From the [[http://book.git-scm.com/3_distributed_workflows.html][Git Community Book]]
415 Once you've set up your repo, you can push changes to it with =ssh=
417 : devel$ git push ssh://user@server/~/public_html/repo.git master
422 : url = ssh://user@server/~/public_html/repo.git
424 to =.git/config=, after which you can push with
426 : devel$ git push public master
428 Note that you may need to copy =.git/description= over by hand. I
429 wrote up a [[http://blog.tremily.us/posts/Git/git-publish.py][git-publish]] script to automate this.
431 ** Gitting comedi, using Git as a frontend for CVS
432 From [[http://issaris.blogspot.com/2005/11/cvs-to-git-and-back.html][Takis blog]]
434 *** Repository creation and setup
436 This is quite similar to [[#svn-migration][svn migration]].
438 **** Create the decoy directory
442 : $ #cvs -d :pserver:anonymous@cvs.comedi.org:/cvs/comedi login
443 : $ git cvsimport -p x -v -d :pserver:anonymous@cvs.comedi.org:/cvs/comedi comedi
445 The login line may not be necessary for other CVS projects.
446 Arguments to =git cvsimport=:
448 |----------+---------------------------------------------------------------------|
450 |----------+---------------------------------------------------------------------|
451 | =-p x= | Pass =-x= to =cvsps=, which ignores any =~/.cvsps/cvsps.cache= file |
452 |----------+---------------------------------------------------------------------|
454 |----------+---------------------------------------------------------------------|
455 | =-d ...= | From http://www.comedi.org/download.html |
456 |----------+---------------------------------------------------------------------|
459 **** Create the clean directory
462 : $ git clone comedi.cvs comedi
464 *** Do your work like normal in comedi
465 *** Update with the latest cvs
468 : $ git cvsimport -p x -v -d :pserver:anonymous@cvs.comedi.org:/cvs/comedi comedi
472 You may have to deal with a [[#conflicting-merge][conflicting merge]].
474 *** Create a patch against the cvs source
476 : $ git format-patch origin
478 * Other useful examples
479 ** Purge all knowledge of a given file or subdir from history
481 For example, in case you accidentally started versioning =/etc/shadow=,
482 or some other document containing sensative information.
484 : $ git filter-branch --index-filter 'git rm -rf --cached --ignore-unmatch /etc/shadow'
485 : $ git reflog expire --expire=0 --all
489 ** Rewrite the repository to look as if foodir/ had been its project root
491 Discarding all other history
493 : $ git filter-branch --subdirectory-filter foodir -- --all
495 ** Merge a single file (with history) into another repository
497 Merge the file =myfile= (with history) from =REPO_A= into =REPO_B=.
499 Create a filtered version of =REPO_A=:
501 : $ git clone REPO_A work-a
503 : $ SPELL='git ls-tree -r --name-only --full-tree "$GIT_COMMIT" | grep -v "[.]git/\|myfile" | grep -v "^[.]git\$" | tr "\n" "\0" | xargs -0 git rm --cached -r --ignore-unmatch'
504 : $ git filter-branch --prune-empty --index-filter "$SPELL" -- --all
506 Alter the =grep= stuff as you need. The goal is to remove anything
507 you want to keep from the listing produced by =SPELL=. If the spell
508 becomes too complicated, you can move it to a standalone script:
510 : $ cat /tmp/spell.sh
514 : $ git filter-branch --prune-empty --index-filter /tmp/spell.sh -- --all
516 Merge it into =REPO_B=:
519 : $ git clone REPO_B work-b
520 : $ git remote add myfile-repo ../work-a
521 : $ git pull myfile-repo master
522 : $ git remote rm myfile-repo
527 : $ rm -rf work-a REPO_B
530 Thanks to [[http://gbayer.com/development/moving-files-from-one-git-repository-to-another-preserving-history/][Greg Bayer]] and [[http://stackoverflow.com/questions/7375528/how-to-extract-one-file-with-commit-history-from-a-git-repo-with-index-filter][Peter Hillerström]].
532 ** Cherry pick a commit from another repository
534 First, give the remote repository a nickname (optional)
536 : $ git remote add bob /home/bob/myrepo
538 Then fetch the remote repo
542 You can merge all the changes Bob made to his master branch with
544 : $ git pull . remotes/bob/master
546 Or cherry-pick a particular one, e.g. commit =1d8fb1fe41dfc1b1eb38c7b5d574577c4b341c58=
548 : $ git cherry-pick 1d8fb1fe41dfc1b1eb38c7b5d574577c4b341c58
550 When a particular remote repo no longer contains interesting material,
551 you can purge the fetched tags and objects with
553 : $ git remote rm bob
554 : $ git remote prune bob
556 ** Restore a deleted file to match an earlier version
557 Source: [[http://stackoverflow.com/questions/953481/restore-a-deleted-file-in-a-git-repo][stackoverflow]].
559 Find the commit that deleted the file in question
561 : $ git rev-list -n 1 HEAD -- <file_path>
565 : $ git log --diff-filter=D --summary
567 Then checkout the file
569 : $ git checkout <deleting_commit>^ -- <file_path>
571 ** Move master.HEAD to a different location
573 Sometimes you screw up and want to drop the thread you've been working
574 on. Place the =HEAD= of the master branch on commit =XYZ= with
577 : $ git branch -D master
578 : $ git branch master XYZ
579 : $ git checkout master
581 Note that this may remove some information from your =.git/config='s
582 =[branch "master"]= entry. You should save your earlier =.git/config=
583 before doing it, and make any appropriate corrections afterwards.
585 If you're just trying to roll back a branch a few commits, skip the
588 : $ git reset --hard HEAD^
590 or add however many =^= you need to get back to the last good commit.
592 *** Rewinding bare repositories
594 If you're trying to [[http://stackoverflow.com/questions/4624881/how-can-i-uncommit-the-last-commit-in-a-git-bare-repository][roll back a few commits in a bare repository]]
597 : $ git update-ref HEAD HEAD^
599 If you're in another branch, use:
601 : $ git update-ref refs/heads/branch-name branch-name^
603 And if you're going back further, use the sha1:
605 : $ git update-ref refs/heads/branch-name a12d48e2
607 ** Git submodules, nesting/tracking sub-repositories.
609 This is a nice way of grouping associated projects. The submodules
610 are included as stand-alone repositories, and the super-project has
611 pointers picking out a particular revision of each submoduel. See the
612 related [[#git-subtrees][Git subtrees]] for an alternate approach.
615 [[http://git.or.cz/gitwiki/GitSubmoduleTutorial][Git Wiki]]
616 [[http://book.git-scm.com/5_submodules.html][Git Book]]
617 [[http://speirs.org/2009/05/11/understanding-git-submodules/][Fraser Speirs: Understanding Git Submodules]]
619 *** Setup a super-module
620 From the [[http://book.git-scm.com/5_submodules.html][Git Book]]
622 : $ git submodule add ~/path/to/submoduleX $submoduleX
624 Warning: Do not use local URLs here if you plan to publish your
625 supermodule. =git submodule add=
627 * clones the submodule under the current directory and by default
628 checks out the master branch.
629 * adds the submodule's clone path to the gitmodules file and adds
630 this file to the index, ready to be committed.
631 * adds the submodule's current commit ID to the index, ready to be
634 : $ git submodule init
636 *** Cloning a super-module
637 From the [[http://git.or.cz/gitwiki/GitSubmoduleTutorial][Git Wiki]]
639 Grab the content living in the super module itself
641 : $ git clone ~/subtut/public/super
643 See how the submodules look
645 : $ git submodule status
646 : -d266b9873ad50488163457f025db7cdd9683d88b a
649 Add submodule repository URLs to .git/config
651 : $ git submodule init
653 Check that they're there if you like
657 : submodule.a.url=/home/moses/subtut/public/a/.git
659 Now check out the referenced submodules
661 : $ git submodule update
663 *** Changing submodules from supermodules
664 From the [[http://git.or.cz/gitwiki/GitSubmoduleTutorial][Git Wiki]]
666 To update a submodule, remember that it's just a checked-out branch in
667 your supermodule. Create and publish the change using the usual
674 : a$ git checkout master
675 : a$ echo "adding a line again" >> a.txt
676 : a$ git commit -a -m "Updated the submodule from within the superproject."
680 Now point the supermodule at the new commit. Warning: don't use
681 =git add a/= or git will think you mean to add the contents of the
682 directory. For submodule updates, you must leave off the trailing
686 : $ git commit -m "Updated submodule a."
690 : index d266b98..261dfac 160000
694 : -Subproject commit d266b9873ad50488163457f025db7cdd9683d88b
695 : +Subproject commit 261dfac35cb99d380eb966e102c1197139f7fa24
697 Take a look at the submodule changes from the supermodule.
699 : $ git submodule summary HEAD^
700 : * a d266b98...261dfac (1):
701 : > Updated the submodule from within the superproject.
703 Publish your updated supermodule.
707 *** Removing submodules
708 From the [[http://git.or.cz/gitwiki/GitSubmoduleTutorial][Git Wiki]]
710 1. Delete the relevant line from the =.gitmodules= file.
711 2. Delete the relevant section from =.git/config=.
712 3. Run =git rm --cached path_to_submodule= (no trailing slash).
713 4. Commit and delete the now untracked submodule files.
716 From the [[http://git.or.cz/gitwiki/GitSubmoduleTutorial][Git Wiki]]
718 It's not safe to run =git submodule update= if you've made changes
719 within a submodule. They will be silently overwritten:
722 From the [[http://git.or.cz/gitwiki/GitSubmoduleTutorial][Git Wiki]]
726 : a$ echo line added from private2 >> a.txt
727 : a$ git commit -a -m "line added inside private2"
729 : $ git submodule update
730 : Submodule path 'a': checked out 'd266b9873ad50488163457f025db7cdd9683d88b'
734 The changes are still visible in the submodule's reflog:
736 : $ git log -g --pretty=oneline
737 : d266b9873ad50488163457f025db7cdd9683d88b HEAD@{0}: checkout: moving to d266b9873ad50488163457f025db7
738 : 4389b0d8e22e616c88a99ebd072cfebba40797ef HEAD@{1}: commit: line added inside private2
739 : d266b9873ad50488163457f025db7cdd9683d88b HEAD@{2}: checkout: moving to d266b9873ad50488163457f025db7
741 ** Git subtrees, merging an entire repository into a subdirectory of your repository
743 :CUSTOM_ID: git-subtrees
747 From [[http://www.kernel.org/pub/software/scm/git/docs/howto/using-merge-subtree.html][kernel.org: merge-subtree]]
749 Name the other project =Bproject=, and fetch.
751 : $ git remote add -f Bproject /path/to/B
753 Prepare for the later step to record the result as a merge.
754 (=-s ours= selects the merge strategy as "keep our version")
756 : $ git merge -s ours --no-commit Bproject/master
758 Read =master= branch of =Bproject= to the subdirectory =dir-B=.
760 : $ git read-tree --prefix=dir-B/ -u Bproject/master
762 Record the merge result.
764 : $ git commit -m "Merge B project as our subdirectory"
766 *** Keeping up to date with the sub-repository source
768 Maintain the result with subsequent pulls/merges using "subtree"
770 : $ git pull -s subtree Bproject master
772 *** Pulling changes back into the sub-repository source
773 From [[http://github.com/apenwarr/git-subtree/tree/master][git-subtree]]
775 The super-project makes some local alterations. Pull/merge them
778 ** Backdating Git tags
780 I rarely bother tagging my projects in the early stages. This is
781 probably a mistake ;), but Git makes it easy to add backdated tags
784 : $ GIT_COMMITTER_DATE="2006-10-02 10:31" git tag -s v1.0.1
786 (from =git tag --help=). Note that you will probably be tagging a
789 : $ GIT_COMMITTER_DATE="2006-10-02 10:31" git tag -s v1.0.1 <commit>
792 [[http://mislav.uniqpath.com/2010/07/git-tips/][mislav]]
795 : $ git diff --word-diff
797 ** Find out if a change is part of a release
799 : $ git name-rev --tags 33db5f4d9027a10e477ccf054b2c1ab94f74c85a
800 : 33db5f4d9027a10e477ccf054b2c1ab94f74c85a tags/v0.99~940
802 Now you are wiser, because you know that it happened 940 revisions
803 before v0.99. A similar command is =git describe=, which finds the
804 latest tag in a commit's history and uses that to construct a name:
806 : $ git describe v1.0.5^2
807 : tags/v1.0.0-21-g975b31d
809 ** List unmerged commits
811 To see what's outstanding in a given branch
813 : $ git cherry [-v] [<upstream> [<head> [<limit>]]]
815 The =-v= option prints summaries as well as the usual commit hashes.
817 ** Remove a remote branch
819 If you want to delete a branch from a repository to which you only
820 have push access, use:
822 : git push repository :branch
824 after deleting the branch in your local repository.
826 ** Clean out your working directory
828 To list files that will be removed (a dry run), use:
832 Then remove the files with
836 |--------+-------------------------------------------------------------|
838 |--------+-------------------------------------------------------------|
839 | =-d= | Remove untracked directories in addition to untracked files |
840 |--------+-------------------------------------------------------------|
841 | =-x= | Don’t use the ignore rules (remove all untracked files) |
842 |--------+-------------------------------------------------------------|
844 |--------+-------------------------------------------------------------|
846 |--------+-------------------------------------------------------------|
848 ** Bisecting a kernel bug (i.e. manual bisection)
850 Although it is possible to automate this (if you have two boxes, one
851 to build kernels and drive the bisection, and one to boot them and
852 check the results), it is also possible to bisect kernel bugs "by
853 hand" using =git bisect=. The man page does a better job describing
854 the process than I will.
856 Note that Git will track the bisection state across reboots, which is
857 convenient for tracking down kernel bugs. You need to run =git bisect
858 reset= to clear that state. If you're nervous, you can save the state
859 on your own with =git bisect log > your-file=.
861 ** Automatic CCs with =git send-email=
863 The Linux kernel and Git mailing list (and other projects) prefer
864 patch submissions via email (vs. pull requests), so that everyone can
865 make line-by-line comments on the submissions before the patches are
866 committed to the main development repositories. The Git commands that
867 facilitate this technique are =format-patch=, =send-email=, and =am=.
868 Here's how things will usually work. We'll start off following the
869 patch developer. It saves typing in the long run if you configure
872 : $ git config --global user.name "John Doe"
873 : $ git config --global user.email jdoe@invalid.com
874 : $ git config --global user.signingkey 0x0123456789ABCDEF
875 : $ git config --global format.thread true
876 : $ git config --global sendemail.cc-cmd ~/bin/git-cc
877 : $ git config --global sendemail.aliasesfile ~/.mutt/aliases
878 : $ git config --global sendemail.aliasfiletype mutt
879 : $ echo 'alias git-list git@vger.kernel.org' >> ~/.mutt/aliases
881 The =git-cc= command is a slick, =git-blame=\-based script by [[http://felipec.wordpress.com/2009/10/25/git-send-email-tricks/][Felipe
882 Contreras]] ([[http://gist.github.com/218093][gist]]).
884 Checkout the source, and start your development branch:
886 : $ git clone git://github.com/gitster/git.git
888 : $ git config sendemail.to git-list
889 : $ git checkout -b dev/my-feature
893 : $ emacs gitweb/gitweb.perl
894 : (hack, hack, hack, …)
895 : $ git commit -am "gitweb: refactor …"
897 If upstream has moved on, rebase your changes onto the new trunk:
899 : $ git checkout master
901 : $ git rebase master dev/my-feature
903 and mail them upstream:
905 : $ git send-email --signoff --annotate --cover-letter origin/master
907 You can record your patches for comparison with:
909 : $ git format-patch --output-directory patch-my-feature-v1 origin/master
911 When you hear back with comments on how to improve the patch set, make
912 the appropriate changes with:
914 : $ git checkout dev/my-feature
916 : $ git checkout master
918 : $ git rebase master dev/my-feature
920 Then send off an updated version:
922 : $ git format-patch --output-directory patch-my-feature-v2 origin/master
923 : $ git diff -ru patch-my-feature-v{1,2} > /tmp/diff-for-cover-letter
924 : $ git send-email --signoff --annotate --cover-letter --subject-prefix 'PATCH v2' origin/master
926 See =gitworkflows(7)= for other good ideas.
928 ** Signing commits with GPG
930 Since version 1.7.9, Git can sign commits with =-S=.
932 : $ git commit -S -m 'Look, a signed commit!'
933 : $ git log --show-signature
935 One more reason to be running =gpg-agent=.
937 ** Fun with =git notes=
939 *** Creating and showing notes
941 Say you have a repository
944 : commit 56db93aebad496c8ec28df0c4c90bed99da57e94
945 : Author: W. Trevor King <wking@tremily.us>
946 : Date: Tue Sep 4 13:21:28 2012 -0400
950 : commit 84b126ce36567260bef8d0bbea03d426c9b7aa6d
951 : Author: W. Trevor King <wking@tremily.us>
952 : Date: Tue Sep 4 13:21:18 2012 -0400
956 You can attach a single note file (per note namespace) to each commit.
958 : $ git notes add -m 'note on commit a' HEAD^
959 : $ git notes add -m 'note on commit b' HEAD
961 : bb511b3526c2300251c482b6f408248c83f22bff 56db93aebad496c8ec28df0c4c90bed99da57e94
962 : 068f07ddec5dfe0a8f93721acbdd7da87dd94db2 84b126ce36567260bef8d0bbea03d426c9b7aa6d
964 The output format is =<note blob sha> <commit sha>=. You can dump a
970 or show the note associated with an object,
972 : $ git notes show HEAD
975 or show the notes in a log.
978 : commit 56db93aebad496c8ec28df0c4c90bed99da57e94
979 : Author: W. Trevor King <wking@tremily.us>
980 : Date: Tue Sep 4 13:21:28 2012 -0400
987 : commit 84b126ce36567260bef8d0bbea03d426c9b7aa6d
988 : Author: W. Trevor King <wking@tremily.us>
989 : Date: Tue Sep 4 13:21:18 2012 -0400
998 You can append new content to an existing note,
1000 : $ git notes append -m 'more notes on commit a' HEAD^
1001 : $ git notes show HEAD^
1004 : more notes on commit a
1006 or spawn your =EDITOR= to make changes.
1008 : $ EDITOR='sed -i "s/more/many/"' git notes edit HEAD^
1009 : $ git notes show HEAD^
1012 : many notes on commit a
1016 You can remove notes.
1018 : $ git notes remove HEAD^
1019 : Removing note for object HEAD^
1021 : bb511b3526c2300251c482b6f408248c83f22bff 56db93aebad496c8ec28df0c4c90bed99da57e94
1025 Git notes have their own references in =refs/notes/...=.
1027 : $ git notes get-ref
1028 : refs/notes/commits
1030 You can use other namespaces besides =commits=.
1032 : $ git notes --ref wtk get-ref
1034 : $ git notes --ref wtk add -m 'wtk note' HEAD
1035 : $ git log --notes=wtk
1036 : commit 56db93aebad496c8ec28df0c4c90bed99da57e94
1037 : Author: W. Trevor King <wking@tremily.us>
1038 : Date: Tue Sep 4 13:21:28 2012 -0400
1045 : commit 84b126ce36567260bef8d0bbea03d426c9b7aa6d
1046 : Author: W. Trevor King <wking@tremily.us>
1047 : Date: Tue Sep 4 13:21:18 2012 -0400
1051 *** Showing notes in the log
1053 If you want to show multiple namespaces in a single log, just keep
1054 adding =--notes= arguments.
1056 : $ git log --notes=wtk --notes
1057 : commit 56db93aebad496c8ec28df0c4c90bed99da57e94
1058 : Author: W. Trevor King <wking@tremily.us>
1059 : Date: Tue Sep 4 13:21:28 2012 -0400
1069 : commit 84b126ce36567260bef8d0bbea03d426c9b7aa6d
1070 : Author: W. Trevor King <wking@tremily.us>
1071 : Date: Tue Sep 4 13:21:18 2012 -0400
1077 You can search through notes for regular expressions.
1079 : $ git grep wtk refs/notes/wtk
1080 : refs/notes/wtk:56db93aebad496c8ec28df0c4c90bed99da57e94:wtk note
1082 The output format here is =<ref>:<commit sha>:<matching line>=.
1086 Because the notes are stored in their own branch, they have their own
1089 : $ git log -p notes/commits
1090 : commit 0625b737c1dd340122478d8e6ae1fe5f8d8ce183
1091 : Author: W. Trevor King <wking@tremily.us>
1092 : Date: Tue Sep 4 13:25:24 2012 -0400
1094 : Notes removed by 'git notes remove'
1096 : diff --git a/84b126ce36567260bef8d0bbea03d426c9b7aa6d b/84b126ce36567260bef8d0bbea03d426c9b7aa6d
1097 : deleted file mode 100644
1098 : index 866bab5..0000000
1099 : --- a/84b126ce36567260bef8d0bbea03d426c9b7aa6d
1104 : -many notes on commit a
1106 : commit b046ea813f3e5324e0910da5e60b3aa933aee2ff
1107 : Author: W. Trevor King <wking@tremily.us>
1108 : Date: Tue Sep 4 13:24:55 2012 -0400
1110 : Notes added by 'git notes edit'
1112 : diff --git a/84b126ce36567260bef8d0bbea03d426c9b7aa6d b/84b126ce36567260bef8d0bbea03d426c9b7aa6d
1113 : index 975b66d..866bab5 100644
1114 : --- a/84b126ce36567260bef8d0bbea03d426c9b7aa6d
1115 : +++ b/84b126ce36567260bef8d0bbea03d426c9b7aa6d
1119 : -more notes on commit a
1120 : +many notes on commit a
1122 : commit d6f6b1e5c8832552e807bcab723e6eaf07d5e5de
1123 : Author: W. Trevor King <wking@tremily.us>
1124 : Date: Tue Sep 4 13:24:16 2012 -0400
1126 : Notes added by 'git notes append'
1128 : diff --git a/84b126ce36567260bef8d0bbea03d426c9b7aa6d b/84b126ce36567260bef8d0bbea03d426c9b7aa6d
1129 : index 068f07d..975b66d 100644
1130 : --- a/84b126ce36567260bef8d0bbea03d426c9b7aa6d
1131 : +++ b/84b126ce36567260bef8d0bbea03d426c9b7aa6d
1135 : +more notes on commit a
1137 : commit 76e670903fcf038b602190a2e0314b265d5a34cf
1138 : Author: W. Trevor King <wking@tremily.us>
1139 : Date: Tue Sep 4 13:22:28 2012 -0400
1141 : Notes added by 'git notes add'
1143 : diff --git a/56db93aebad496c8ec28df0c4c90bed99da57e94 b/56db93aebad496c8ec28df0c4c90bed99da57e94
1144 : new file mode 100644
1145 : index 0000000..bb511b3
1147 : +++ b/56db93aebad496c8ec28df0c4c90bed99da57e94
1151 : commit 62b129c10cdfc8ec9f9d204dac04a5cf0562dffe
1152 : Author: W. Trevor King <wking@tremily.us>
1153 : Date: Tue Sep 4 13:22:21 2012 -0400
1155 : Notes added by 'git notes add'
1157 : diff --git a/84b126ce36567260bef8d0bbea03d426c9b7aa6d b/84b126ce36567260bef8d0bbea03d426c9b7aa6d
1158 : new file mode 100644
1159 : index 0000000..068f07d
1161 : +++ b/84b126ce36567260bef8d0bbea03d426c9b7aa6d
1165 You can checkout the note branch just like any other branch.
1167 : $ git checkout notes/commits
1169 Where you will find one file for each note, where the filename is the
1170 hash of the object that the note is about.
1173 : 56db93aebad496c8ec28df0c4c90bed99da57e94
1174 : $ cat 56db93aebad496c8ec28df0c4c90bed99da57e94
1177 You can do all your usual manipulations in the note branch, merging,
1178 rebasing, updating refs, etc.
1180 : $ git update-ref refs/notes/commits b046ea
1182 : bb511b3526c2300251c482b6f408248c83f22bff 56db93aebad496c8ec28df0c4c90bed99da57e94
1183 : 866bab52944f009b3f92c61beea7a8a7fad0e0a2 84b126ce36567260bef8d0bbea03d426c9b7aa6d
1185 *** Adding notes to non-commit objects
1187 There's no reason you need to limit your notes to commits. However,
1188 you'll need the hash for the object you're tagging. Here's how you
1189 can get a hash for a file:
1191 : $ git hash-object a
1192 : 78981922613b2afb6025042ff6bd878ac1994e85
1194 Alternatively, you can list all the files in a directory.
1196 : $ ls-tree HEAD^{tree}
1197 : 100644 blob 78981922613b2afb6025042ff6bd878ac1994e85 a
1198 : 100644 blob 61780798228d17af2d34fce4cfbdf35556832472 b
1200 Then attach your note to the object directly.
1202 : $ git notes add -m 'note on blob a' 789819
1203 : $ $ git notes show $(git hash-object a)
1208 **** Naming remote note references
1210 It's a good idea to place all of your note references under
1211 =refs/notes=, because the current (2012-09-04) implementation of
1212 =expand_notes_ref= in =git/notes.c= is:
1214 : void expand_notes_ref(struct strbuf *sb)
1216 : if (!prefixcmp(sb->buf, "refs/notes/"))
1217 : return; /* we're happy */
1218 : else if (!prefixcmp(sb->buf, "notes/"))
1219 : strbuf_insert(sb, 0, "refs/", 5);
1221 : strbuf_insert(sb, 0, "refs/notes/", 11);
1226 : refs/notes/commits → refs/notes/commits
1227 : notes/commits → refs/notes/commits
1228 : commits → refs/notes/commits
1232 : refs/remotes/origin/notes/commits → refs/notes/refs/remotes/origin/notes/commits
1234 which is probably not what you wanted.
1236 For more details about why this is the case, read [[http://thread.gmane.org/gmane.comp.version-control.git/160503][this thread]].
1238 **** Fast forward merges
1240 You can check out the note branch and pull/push/merge just like any
1241 other branch, but there is also a user interface for merging notes
1242 without bothering to checkout the note branch. To see this in action,
1243 we'll need to clone our repo.
1246 : $ git clone repo-a repo-b
1247 : Cloning into 'repo-b'...
1251 Git doesn't fetch (or push) notes by default, so we'll have to add a
1254 : $ git config --add remote.origin.fetch '+refs/notes/*:refs/notes/remotes/origin/*'
1257 : * [new ref] refs/notes/commits -> refs/notes/remotes/origin/commits
1258 : * [new ref] refs/notes/wtk -> refs/notes/remotes/origin/wtk
1260 Alrighty, let's make those note's our own.
1262 : $ git notes merge origin/notes/commits
1263 : fatal: Cannot merge empty notes ref (refs/notes/origin/notes/commits) into empty notes ref (refs/notes/commits)
1265 Hmm, looks like the initial commit may be troublesome. Let's adopt
1266 the current remote state.
1268 : $ git update-ref refs/notes/commits refs/notes/remotes/origin/commits
1270 : bb511b3526c2300251c482b6f408248c83f22bff 56db93aebad496c8ec28df0c4c90bed99da57e94
1271 : a4c2f4dcfdb7d547bc303282f2678581a9ebf35f 78981922613b2afb6025042ff6bd878ac1994e85
1272 : 866bab52944f009b3f92c61beea7a8a7fad0e0a2 84b126ce36567260bef8d0bbea03d426c9b7aa6d
1274 And make some changes.
1276 : EDITOR='sed -i "N;/\nmany/s/\nmany/extra/;P;D"' git notes edit HEAD^
1277 : git notes show HEAD^
1279 : extra notes on commit a
1281 Now go back to the original repo and fetch the changes.
1284 : $ git remote add repo-b ../repo-b
1285 : $ git config --add remote.repo-b.fetch '+refs/notes/*:refs/notes/remotes/repo-b/*'
1286 : $ git fetch repo-b
1287 : remote: Counting objects: 5, done.
1288 : remote: Compressing objects: 100% (2/2), done.
1289 : remote: Total 3 (delta 1), reused 0 (delta 0)
1290 : Unpacking objects: 100% (3/3), done.
1292 : * [new branch] master -> repo-b/master
1293 : * [new ref] refs/notes/commits -> refs/notes/remotes/repo-b/commits
1294 : $ git diff notes/commits notes/remotes/repo-b/commits
1295 : diff --git a/84b126ce36567260bef8d0bbea03d426c9b7aa6d b/84b126ce36567260bef8d0bbea03d426c9b7aa6d
1296 : index 866bab5..710e3e0 100644
1297 : --- a/84b126ce36567260bef8d0bbea03d426c9b7aa6d
1298 : +++ b/84b126ce36567260bef8d0bbea03d426c9b7aa6d
1302 : -many notes on commit a
1303 : +extra notes on commit a
1307 : $ git notes merge -v remotes/repo-b/commits
1310 **** Resolving conflicts
1312 Set up conflicting changes.
1314 : repo-a$ EDITOR='sed -i "s/extra/tons of/"' git notes edit HEAD^
1315 : repo-b$ EDITOR='sed -i "s/extra/lots of/"' git notes edit HEAD^
1317 : remote: Counting objects: 5, done.
1318 : remote: Compressing objects: 100% (2/2), done.
1319 : remote: Total 3 (delta 1), reused 0 (delta 0)
1320 : Unpacking objects: 100% (3/3), done.
1322 : 69e6240..bf61bfc refs/notes/commits -> refs/notes/remotes/origin/commits
1323 : repo-b$ git diff refs/notes/commits refs/notes/remotes/origin/commits
1324 : diff --git a/84b126ce36567260bef8d0bbea03d426c9b7aa6d b/84b126ce36567260bef8d0bbea03d426c9b7aa6d
1325 : index 0808976..b847e1d 100644
1326 : --- a/84b126ce36567260bef8d0bbea03d426c9b7aa6d
1327 : +++ b/84b126ce36567260bef8d0bbea03d426c9b7aa6d
1330 : -lots of notes on commit a
1331 : +tons of notes on commit a
1333 Try to merge =repo-a= from =repo-b=.
1335 : $ git notes merge refs/notes/remotes/origin/commits
1336 : Auto-merging notes for 84b126ce36567260bef8d0bbea03d426c9b7aa6d
1337 : CONFLICT (content): Merge conflict in notes for object 84b126ce36567260bef8d0bbea03d426c9b7aa6d
1338 : Automatic notes merge failed. Fix conflicts in .git/NOTES_MERGE_WORKTREE and commit the result with 'git notes merge --commit', or abort the merge with 'git notes merge --abort'.
1339 : $ ls .git/NOTES_MERGE_WORKTREE/
1340 : 84b126ce36567260bef8d0bbea03d426c9b7aa6d
1341 : $ cat .git/NOTES_MERGE_WORKTREE/84b126ce36567260bef8d0bbea03d426c9b7aa6d
1343 : <<<<<<< refs/notes/commits
1344 : lots of notes on commit a
1346 : tons of notes on commit a
1347 : >>>>>>> refs/notes/remotes/origin/commits
1348 : $ emacs .git/NOTES_MERGE_WORKTREE/84b126ce36567260bef8d0bbea03d426c9b7aa6d
1349 : <edit as you see fit>
1350 : $ git notes merge --commit
1351 : $ git notes show HEAD^
1353 : zounds of notes on commit a
1355 You can also set some useful merge strategies. Lets go back and try
1356 the merge again. First, undo the merge
1358 : $ git update-ref refs/notes/commits refs/notes/commits^
1359 : $ git diff refs/notes/commits refs/notes/remotes/origin/commits
1360 : diff --git a/84b126ce36567260bef8d0bbea03d426c9b7aa6d b/84b126ce36567260bef8d0bbea03d426c9b7aa6d
1361 : index 0808976..b847e1d 100644
1362 : --- a/84b126ce36567260bef8d0bbea03d426c9b7aa6d
1363 : +++ b/84b126ce36567260bef8d0bbea03d426c9b7aa6d
1366 : -lots of notes on commit a
1367 : +tons of notes on commit a
1369 Now merge with a particular strategy.
1371 : $ git notes merge --strategy=cat_sort_uniq refs/notes/remotes/origin/commits
1372 : Concatenating unique lines in local and remote notes for 84b126ce36567260bef8d0bbea03d426c9b7aa6d
1373 : $ git notes show HEAD^
1374 : lots of notes on commit a
1376 : tons of notes on commit a
1378 There are more details about the available merge strategies in =git
1382 ** Git commit hangs with no output
1384 You probably corrupted something in =.git=.
1389 fixed the problem for me.
1391 ** Conflicting merge
1393 :CUSTOM_ID: conflicting-merge
1396 =git pull= or =git merge= aborts with =merge-failed= or some such.
1397 This leaves your checked out branch in a state where
1401 shows the merge difficulties. You can either [[#abort-merge][abort the merge]], or
1402 [[#hand-merge][merge by hand]].
1406 :CUSTOM_ID: abort-merge
1409 : $ git reset --hard HEAD
1413 :CUSTOM_ID: hand-merge
1416 Edit the marked packages as you see fit. Then let Git know you've
1417 accepted your changes with either
1419 : $ git update-index
1423 : $ git add CONFLICT_FILE