Browse Source

GIT 0.99.9n aka 1.0rc6

Oh, I hate to do this but I ended up merging big usage string
cleanups from Fredrik, git-am enhancements that made a lot of
sense for non mbox users from HPA, and rebase changes (done
independently by me and Lukas) among other things, so git is
still in perpetual state of 1.0rc.  1.0 will probably be next
Wednesday, but who knows.

Signed-off-by: Junio C Hamano <junkio@cox.net>
maint v1.0rc6
Junio C Hamano 19 years ago
parent
commit
1ed91937e5
  1. 302
      Documentation/everyday.txt
  2. 2
      Documentation/git-am.txt
  3. 26
      Documentation/git-branch.txt
  4. 10
      Documentation/git-checkout.txt
  5. 21
      Documentation/git-clone.txt
  6. 2
      Documentation/git-cvsexportcommit.txt
  7. 62
      Documentation/git-diff.txt
  8. 9
      Documentation/git-format-patch.txt
  9. 7
      Documentation/git-init-db.txt
  10. 9
      Documentation/git-mailsplit.txt
  11. 70
      Documentation/git-reset.txt
  12. 60
      Documentation/git.txt
  13. 7
      Documentation/howto/using-topic-branches.txt
  14. 3
      Documentation/technical/pack-protocol.txt
  15. 20
      Documentation/tutorial.txt
  16. 4
      Makefile
  17. 2
      checkout-index.c
  18. 6
      debian/changelog
  19. 7
      diffcore-break.c
  20. 13
      git-add.sh
  21. 22
      git-am.sh
  22. 6
      git-applymbox.sh
  23. 4
      git-applypatch.sh
  24. 24
      git-bisect.sh
  25. 21
      git-branch.sh
  26. 6
      git-checkout.sh
  27. 13
      git-cherry.sh
  28. 7
      git-clone.sh
  29. 5
      git-commit.sh
  30. 3
      git-compat-util.h
  31. 5
      git-fetch.sh
  32. 25
      git-format-patch.sh
  33. 7
      git-grep.sh
  34. 10
      git-lost-found.sh
  35. 11
      git-merge.sh
  36. 3
      git-prune.sh
  37. 13
      git-pull.sh
  38. 7
      git-push.sh
  39. 33
      git-rebase.sh
  40. 3
      git-repack.sh
  41. 12
      git-request-pull.sh
  42. 6
      git-reset.sh
  43. 6
      git-resolve.sh
  44. 19
      git-revert.sh
  45. 34
      git-sh-setup.sh
  46. 11
      git-status.sh
  47. 14
      git-tag.sh
  48. 12
      git-verify-tag.sh
  49. 32
      mailinfo.c
  50. 91
      mailsplit.c
  51. 6
      send-pack.c
  52. 4
      t/t3200-branch.sh
  53. 34
      t/t3400-rebase.sh
  54. 10
      t/t5400-send-pack.sh

302
Documentation/everyday.txt

@ -50,6 +50,38 @@ Everybody uses these commands to feed and care git repositories. @@ -50,6 +50,38 @@ Everybody uses these commands to feed and care git repositories.

* gitlink:git-repack[1] to pack loose objects for efficiency.

Examples
~~~~~~~~

Check health and remove cruft.::
+
------------
$ git fsck-objects <1>
$ git prune
$ git count-objects <2>
$ git repack <3>
$ git prune <4>

<1> running without "--full" is usually cheap and assures the
repository health reasonably well.
<2> check how many loose objects there are and how much
diskspace is wasted by not repacking.
<3> without "-a" repacks incrementally. repacking every 4-5MB
of loose objects accumulation may be a good rule of thumb.
<4> after repack, prune removes the duplicate loose objects.
------------

Repack a small project into single pack.::
+
------------
$ git repack -a -d <1>
$ git prune

<1> pack all the objects reachable from the refs into one pack
and remove unneeded other packs
------------


Individual Developer (Standalone)[[Individual Developer (Standalone)]]
----------------------------------------------------------------------

@ -59,9 +91,6 @@ following commands. @@ -59,9 +91,6 @@ following commands.

* gitlink:git-show-branch[1] to see where you are.

* gitlink:git-diff[1] and gitlink:git-status[1] to see what
you are in the middle of doing.

* gitlink:git-log[1] to see what happened.

* gitlink:git-whatchanged[1] to find out where things have
@ -70,7 +99,11 @@ following commands. @@ -70,7 +99,11 @@ following commands.
* gitlink:git-checkout[1] and gitlink:git-branch[1] to switch
branches.

* gitlink:git-update-index[1] to manage the index file.
* gitlink:git-add[1] and gitlink:git-update-index[1] to manage
the index file.

* gitlink:git-diff[1] and gitlink:git-status[1] to see what
you are in the middle of doing.

* gitlink:git-commit[1] to advance the current branch.

@ -82,6 +115,63 @@ following commands. @@ -82,6 +115,63 @@ following commands.

* gitlink:git-rebase[1] to maintain topic branches.

* gitlink:git-tag[1] to mark known point.

Examples
~~~~~~~~

Extract a tarball and create a working tree and a new repository to keep track of it.::
+
------------
$ tar zxf frotz.tar.gz
$ cd frotz
$ git-init-db
$ git add . <1>
$ git commit -m 'import of frotz source tree.'
$ git tag v2.43 <2>

<1> add everything under the current directory.
<2> make a lightweight, unannotated tag.
------------

Create a topic branch and develop.::
+
------------
$ git checkout -b alsa-audio <1>
$ edit/compile/test
$ git checkout -- curses/ux_audio_oss.c <2>
$ git add curses/ux_audio_alsa.c <3>
$ edit/compile/test
$ git diff <4>
$ git commit -a -s <5>
$ edit/compile/test
$ git reset --soft HEAD^ <6>
$ edit/compile/test
$ git diff ORIG_HEAD <7>
$ git commit -a -c ORIG_HEAD <8>
$ git checkout master <9>
$ git pull . alsa-audio <10>
$ git log --since='3 days ago' <11>
$ git log v2.43.. curses/ <12>

<1> create a new topic branch.
<2> revert your botched changes in "curses/ux_audio_oss.c".
<3> you need to tell git if you added a new file; removal and
modification will be caught if you do "commit -a" later.
<4> to see what changes you are committing.
<5> commit everything as you have tested, with your sign-off.
<6> take the last commit back, keeping what is in the working tree.
<7> look at the changes since the premature commit we took back.
<8> redo the commit undone in the previous step, using the message
you originally wrote.
<9> switch to the master branch.
<10> merge a topic branch into your master branch
<11> review commit logs; other forms to limit output can be
combined and include --max-count=10 (show 10 commits), --until='2005-12-10'.
<12> view only the changes that touch what's in curses/
directory, since v2.43 tag.
------------


Individual Developer (Participant)[[Individual Developer (Participant)]]
------------------------------------------------------------------------
@ -90,15 +180,93 @@ A developer working as a participant in a group project needs to @@ -90,15 +180,93 @@ A developer working as a participant in a group project needs to
learn how to communicate with others, and uses these commands in
addition to the ones needed by a standalone developer.

* gitlink:git-pull[1] from "origin" to keep up-to-date with
the upstream.
* gitlink:git-clone[1] from the upstream to prime your local
repository.

* gitlink:git-pull[1] and gitlink:git-fetch[1] from "origin"
to keep up-to-date with the upstream.

* gitlink:git-push[1] to shared repository if you adopt CVS
* gitlink:git-push[1] to shared repository, if you adopt CVS
style shared repository workflow.

* gitlink:git-format-patch[1] to prepare e-mail submission, if
you adopt Linux kernel-style public forum workflow.

Examples
~~~~~~~~

Clone the upstream and work on it. Feed changes to upstream.::
+
------------
$ git clone git://git.kernel.org/pub/scm/.../torvalds/linux-2.6 my2.6
$ cd my2.6
$ edit/compile/test; git commit -a -s <1>
$ git format-patch origin <2>
$ git pull <3>
$ git whatchanged -p ORIG_HEAD.. arch/i386 include/asm-i386 <4>
$ git pull git://git.kernel.org/pub/.../jgarzik/libata-dev.git ALL <5>
$ git reset --hard ORIG_HEAD <6>
$ git prune <7>
$ git fetch --tags <8>

<1> repeat as needed.
<2> extract patches from your branch for e-mail submission.
<3> "pull" fetches from "origin" by default and merges.
<4> look at the changes since last time we checked, only in the
area we are interested in.
<5> fetch from a specific branch from a specific repository and and merge.
<6> revert the pull.
<7> garbage collect leftover objects from reverted pull.
<8> from time to time, obtain official tags from the "origin"
and store them under .git/refs/tags/.
------------


Push into another repository.::
+
------------
satellite$ git clone mothership:frotz/.git frotz <1>
satellite$ cd frotz
satellite$ cat .git/remotes/origin <2>
URL: mothership:frotz/.git
Pull: master:origin
satellite$ echo 'Push: master:satellite' >>.git/remotes/origin <3>
satellite$ edit/compile/test/commit
satellite$ git push origin <4>

mothership$ cd frotz
mothership$ git checkout master
mothership$ git pull . satellite <5>

<1> mothership machine has a frotz repository under your home
directory; clone from it to start a repository on the satellite
machine.
<2> clone creates this file by default. It arranges "git pull"
to fetch and store the master branch head of mothership machine
to local "origin" branch.
<3> arrange "git push" to push local "master" branch to
"satellite" branch of the mothership machine.
<4> push will stash our work away on "satellite" branch on the
mothership machine. You could use this as a back-up method.
<5> on mothership machine, merge the work done on the satellite
machine into the master branch.
------------

Branch off of a specific tag.::
+
------------
$ git checkout -b private2.6.14 v2.6.14 <1>
$ edit/compile/test; git commit -a
$ git checkout master
$ git format-patch -k -m --stdout v2.6.14..private2.6.14 |
git am -3 -k <2>

<1> create a private branch based on a well known (but somewhat behind)
tag.
<2> forward port all changes in private2.6.14 branch to master branch
without a formal "merging".
------------


Integrator[[Integrator]]
------------------------
@ -121,6 +289,62 @@ commands in addition to the ones needed by participants. @@ -121,6 +289,62 @@ commands in addition to the ones needed by participants.
* gitlink:git-push[1] to publish the bleeding edge.


Examples
~~~~~~~~

My typical GIT day.::
+
------------
$ git status <1>
$ git show-branch <2>
$ mailx <3>
& s 2 3 4 5 ./+to-apply
& s 7 8 ./+hold-linus
& q
$ git checkout master
$ git am -3 -i -s -u ./+to-apply <4>
$ compile/test
$ git checkout -b hold/linus && git am -3 -i -s -u ./+hold-linus <5>
$ git checkout topic/one && git rebase master <6>
$ git checkout pu && git reset --hard master <7>
$ git pull . topic/one topic/two && git pull . hold/linus <8>
$ git checkout maint
$ git cherry-pick master~4 <9>
$ compile/test
$ git tag -s -m 'GIT 0.99.9x' v0.99.9x <10>
$ git fetch ko && git show-branch master maint 'tags/ko-*' <11>
$ git push ko <12>
$ git push ko v0.99.9x <13>

<1> see what I was in the middle of doing, if any.
<2> see what topic branches I have and think about how ready
they are.
<3> read mails, save ones that are applicable, and save others
that are not quite ready.
<4> apply them, interactively, with my sign-offs.
<5> create topic branch as needed and apply, again with my
sign-offs.
<6> rebase internal topic branch that has not been merged to the
master, nor exposed as a part of a stable branch.
<7> restart "pu" every time from the master.
<8> and bundle topic branches still cooking.
<9> backport a critical fix.
<10> create a signed tag.
<11> make sure I did not accidentally rewound master beyond what I
already pushed out. "ko" shorthand points at the repository I have
at kernel.org, and looks like this:
$ cat .git/remotes/ko
URL: kernel.org:/pub/scm/git/git.git
Pull: master:refs/tags/ko-master
Pull: maint:refs/tags/ko-maint
Push: master
Push: +pu
Push: maint
<12> push out the bleeding edge.
<13> push the tag out, too.
------------


Repository Administration[[Repository Administration]]
------------------------------------------------------

@ -136,3 +360,67 @@ and maintain access to the repository by developers. @@ -136,3 +360,67 @@ and maintain access to the repository by developers.
* link:howto/update-hook-example.txt[update hook howto] has a
good example of managing a shared central repository.


Examples
~~~~~~~~

Run git-daemon to serve /pub/scm from inetd.::
+
------------
$ grep git /etc/inet.conf
git stream tcp nowait nobody \
/usr/bin/git-daemon git-daemon --inetd --syslog --export-all /pub/scm
------------
+
The actual configuration line should be on one line.

Give push/pull only access to developers.::
+
------------
$ grep git /etc/passwd <1>
alice:x:1000:1000::/home/alice:/usr/bin/git-shell
bob:x:1001:1001::/home/bob:/usr/bin/git-shell
cindy:x:1002:1002::/home/cindy:/usr/bin/git-shell
david:x:1003:1003::/home/david:/usr/bin/git-shell
$ grep git /etc/shells <2>
/usr/bin/git-shell

<1> log-in shell is set to /usr/bin/git-shell, which does not
allow anything but "git push" and "git pull". The users should
get an ssh access to the machine.
<2> in many distributions /etc/shells needs to list what is used
as the login shell.
------------

CVS-style shared repository.::
+
------------
$ grep git /etc/group <1>
git:x:9418:alice,bob,cindy,david
$ cd /home/devo.git
$ ls -l <2>
lrwxrwxrwx 1 david git 17 Dec 4 22:40 HEAD -> refs/heads/master
drwxrwsr-x 2 david git 4096 Dec 4 22:40 branches
-rw-rw-r-- 1 david git 84 Dec 4 22:40 config
-rw-rw-r-- 1 david git 58 Dec 4 22:40 description
drwxrwsr-x 2 david git 4096 Dec 4 22:40 hooks
-rw-rw-r-- 1 david git 37504 Dec 4 22:40 index
drwxrwsr-x 2 david git 4096 Dec 4 22:40 info
drwxrwsr-x 4 david git 4096 Dec 4 22:40 objects
drwxrwsr-x 4 david git 4096 Nov 7 14:58 refs
drwxrwsr-x 2 david git 4096 Dec 4 22:40 remotes
$ ls -l hooks/update <3>
-r-xr-xr-x 1 david git 3536 Dec 4 22:40 update
$ cat info/allowed-users <4>
refs/heads/master alice\|cindy
refs/heads/doc-update bob
refs/tags/v[0-9]* david

<1> place the developers into the same git group.
<2> and make the shared repository writable by the group.
<3> use update-hook example by Carl from Documentation/howto/
for branch policy control.
<4> alice and cindy can push into master, only bob can push into doc-update.
david is the release manager and is the only person who can
create and push version tags.
------------

2
Documentation/git-am.txt

@ -69,7 +69,7 @@ recover from this in one of two ways: @@ -69,7 +69,7 @@ recover from this in one of two ways:

. hand resolve the conflict in the working directory, and update
the index file to bring it in a state that the patch should
have produced. Then run the command with '--resume' option.
have produced. Then run the command with '--resolved' option.

The command refuses to process new mailboxes while `.dotest`
directory exists, so if you decide to start over from scratch,

26
Documentation/git-branch.txt

@ -32,6 +32,32 @@ start-point:: @@ -32,6 +32,32 @@ start-point::
Where to create the branch; defaults to HEAD. This
option has no meaning with -d and -D.


Examples
~~~~~~~~

Start development off of a know tag::
+
------------
$ git clone git://git.kernel.org/pub/scm/.../linux-2.6 my2.6
$ cd my2.6
$ git branch my2.6.14 v2.6.14 <1>
$ git checkout my2.6.14

<1> These two steps are the same as "checkout -b my2.6.14 v2.6.14".
------------

Delete unneeded branch::
+
------------
$ git clone git://git.kernel.org/.../git.git my.git
$ cd my.git
$ git branch -D todo <1>

<1> delete todo branch even if the "master" branch does not have all
commits from todo branch.
------------

Author
------
Written by Linus Torvalds <torvalds@osdl.org> and Junio C Hamano <junkio@cox.net>

10
Documentation/git-checkout.txt

@ -50,10 +50,14 @@ the `Makefile` to two revisions back, deletes hello.c by @@ -50,10 +50,14 @@ the `Makefile` to two revisions back, deletes hello.c by
mistake, and gets it back from the index.

------------
$ git checkout master
$ git checkout master~2 Makefile
$ git checkout master <1>
$ git checkout master~2 Makefile <2>
$ rm -f hello.c
$ git checkout hello.c
$ git checkout hello.c <3>

<1> switch branch
<2> take out a file out of other commit
<3> or "git checkout -- hello.c", as in the next example.
------------

If you have an unfortunate branch that is named `hello.c`, the

21
Documentation/git-clone.txt

@ -74,10 +74,31 @@ OPTIONS @@ -74,10 +74,31 @@ OPTIONS
for "host.xz:foo/.git"). Cloning into an existing directory
is not allowed.

Examples
~~~~~~~~

Clone from upstream::
+
------------
$ git clone git://git.kernel.org/pub/scm/.../linux-2.6 my2.6
$ cd my2.6
$ make
------------


Make a local clone that borrows from the current directory, without checking things out::
+
------------
$ git clone -l -s -n . ../copy
$ cd copy
$ git show-branch
------------

Author
------
Written by Linus Torvalds <torvalds@osdl.org>


Documentation
--------------
Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.

2
Documentation/git-cvsexportcommit.txt

@ -8,7 +8,7 @@ git-cvsexportcommit - Export a commit to a CVS checkout @@ -8,7 +8,7 @@ git-cvsexportcommit - Export a commit to a CVS checkout

SYNOPSIS
--------
git-cvsapplycommmit.perl
git-cvsexportcommmit.perl
[ -h ] [ -v ] [ -c ] [ -p ] [PARENTCOMMIT] COMMITID



62
Documentation/git-diff.txt

@ -40,6 +40,68 @@ OPTIONS @@ -40,6 +40,68 @@ OPTIONS
commands.


EXAMPLES
--------

Various ways to check your working tree::
+
------------
$ git diff <1>
$ git diff --cached <2>
$ git diff HEAD <3>

<1> changes in the working tree since your last git-update-index.
<2> changes between the index and your last commit; what you
would be committing if you run "git commit" without "-a" option.
<3> changes in the working tree since your last commit; what you
would be committing if you run "git commit -a"
------------

Comparing with arbitrary commits::
+
------------
$ git diff test <1>
$ git diff HEAD -- ./test <2>
$ git diff HEAD^ HEAD <3>

<1> instead of using the tip of the current branch, compare with the
tip of "test" branch.
<2> instead of comparing with the tip of "test" branch, compare with
the tip of the curren branch, but limit the comparison to the
file "test".
<3> compare the version before the last commit and the last commit.
------------


Limiting the diff output::
+
------------
$ git diff --diff-filter=MRC <1>
$ git diff --name-status -r <2>
$ git diff arch/i386 include/asm-i386 <3>

<1> show only modification, rename and copy, but not addition
nor deletion.
<2> show only names and the nature of change, but not actual
diff output. --name-status disables usual patch generation
which in turn also disables recursive behaviour, so without -r
you would only see the directory name if there is a change in a
file in a subdirectory.
<3> limit diff output to named subtrees.
------------

Munging the diff output::
+
------------
$ git diff --find-copies-harder -B -C <1>
$ git diff -R <2>

<1> spend extra cycles to find renames, copies and complete
rewrites (very expensive).
<2> output diff in reverse.
------------


Author
------
Written by Linus Torvalds <torvalds@osdl.org>

9
Documentation/git-format-patch.txt

@ -84,6 +84,15 @@ git-format-patch origin:: @@ -84,6 +84,15 @@ git-format-patch origin::
pulled from origin the last time in a patch form for
e-mail submission.

git-format-patch -M -B origin::
The same as the previous one, except detect and handle
renames and complete rewrites intelligently to produce
renaming patch. A renaming patch reduces the amount of
text output, and generally makes it easier to review
it. Note that the "patch" program does not understand
renaming patch well, so use it only when you know the
recipient uses git to apply your patch.


See Also
--------

7
Documentation/git-init-db.txt

@ -40,9 +40,12 @@ Start a new git repository for an existing code base:: @@ -40,9 +40,12 @@ Start a new git repository for an existing code base::
+
----------------
$ cd /path/to/my/codebase
$ git-init-db
----------------
$ git-init-db <1>
$ git-add . <2>

<1> prepare /path/to/my/codebase/.git directory
<2> add all existing file to the index
----------------


Author

9
Documentation/git-mailsplit.txt

@ -7,7 +7,7 @@ git-mailsplit - Totally braindamaged mbox splitter program. @@ -7,7 +7,7 @@ git-mailsplit - Totally braindamaged mbox splitter program.

SYNOPSIS
--------
'git-mailsplit' [-d<prec>] [<mbox>] <directory>
'git-mailsplit' [-b] [-f<nn>] [-d<prec>] -o<directory> [--] [<mbox>...]

DESCRIPTION
-----------
@ -23,11 +23,18 @@ OPTIONS @@ -23,11 +23,18 @@ OPTIONS
<directory>::
Directory in which to place the individual messages.

-b::
If any file doesn't begin with a From line, assume it is a
single mail message instead of signalling error.

-d<prec>::
Instead of the default 4 digits with leading zeros,
different precision can be specified for the generated
filenames.

-f<nn>::
Skip the first <nn> numbers, for example if -f3 is specified,
start the numbering with 0004.

Author
------

70
Documentation/git-reset.txt

@ -42,6 +42,76 @@ OPTIONS @@ -42,6 +42,76 @@ OPTIONS
<commit-ish>::
Commit to make the current HEAD.

Examples
~~~~~~~~

Undo a commit and redo::
+
------------
$ git commit ...
$ git reset --soft HEAD^ <1>
$ edit <2>
$ git commit -a -c ORIG_HEAD <3>

<1> This is most often done when you remembered what you
just committed is incomplete, or you misspelled your commit
message, or both. Leaves working tree as it was before "reset".
<2> make corrections to working tree files.
<3> "reset" copies the old head to .git/ORIG_HEAD; redo the
commit by starting with its log message. If you do not need to
edit the message further, you can give -C option instead.
------------

Undo commits permanently::
+
------------
$ git commit ...
$ git reset --hard HEAD~3 <1>

<1> The last three commits (HEAD, HEAD^, and HEAD~2) were bad
and you do not want to ever see them again. Do *not* do this if
you have already given these commits to somebody else.
------------

Undo a commit, making it a topic branch::
+
------------
$ git branch topic/wip <1>
$ git reset --hard HEAD~3 <2>
$ git checkout topic/wip <3>

<1> You have made some commits, but realize they were premature
to be in the "master" branch. You want to continue polishing
them in a topic branch, so create "topic/wip" branch off of the
current HEAD.
<2> Rewind the master branch to get rid of those three commits.
<3> Switch to "topic/wip" branch and keep working.
------------

Undo update-index::
+
------------
$ edit <1>
$ git-update-index frotz.c filfre.c
$ mailx <2>
$ git reset <3>
$ git pull git://info.example.com/ nitfol <4>

<1> you are happily working on something, and find the changes
in these files are in good order. You do not want to see them
when you run "git diff", because you plan to work on other files
and changes with these files are distracting.
<2> somebody asks you to pull, and the changes sounds worthy of merging.
<3> however, you already dirtied the index (i.e. your index does
not match the HEAD commit). But you know the pull you are going
to make does not affect frotz.c nor filfre.c, so you revert the
index changes for these two files. Your changes in working tree
remain there.
<4> then you can pull and merge, leaving frotz.c and filfre.c
changes still in the working tree.
------------


Author
------
Written by Junio C Hamano <junkio@cox.net> and Linus Torvalds <torvalds@osdl.org>

60
Documentation/git.txt

@ -33,34 +33,41 @@ OPTIONS @@ -33,34 +33,41 @@ OPTIONS
environment variable. If no path is given 'git' will print
the current setting and then exit.

CORE GIT COMMANDS
-----------------
Before reading this cover to cover, you may want to take a look
at the link:tutorial.html[tutorial] document. If you are
migrating from CVS, link:cvs-migration.html[cvs migration]
document may be helpful after you finish the tutorial.

The <<Discussion>> section below contains much useful definition
and clarification info - read that first. After that, if you
are interested in using git to manage (version control)

NOT LEARNING CORE GIT COMMANDS
------------------------------

This manual is intended to give complete background information
and internal workings of git, which may be too much for most
people. The <<Discussion>> section below contains much useful
definition and clarification - read that first.

If you are interested in using git to manage (version control)
projects, use link:everyday.html[Everyday GIT] as a guide to the
minimum set of commands you need to know for day-to-day work.
Most likely, that will get you started, and you can go a long
way without knowing the low level details too much.

The link:tutorial.html[tutorial] document covers how things
internally work.

If you are migrating from CVS, link:cvs-migration.html[cvs
migration] document may be helpful after you finish the
tutorial.

After you get the general feel from the tutorial and this
overview page, you may want to take a look at the
link:howto-index.html[howto] documents.


CORE GIT COMMANDS
-----------------

If you are writing your own Porcelain, you need to be familiar
with most of the low level commands --- I suggest starting from
gitlink:git-update-index[1] and gitlink:git-read-tree[1].


David Greaves <david@dgreaves.com>
08/05/05

Updated by Junio C Hamano <junkio@cox.net> on 2005-05-05 and
further on 2005-12-07 to reflect recent changes.

Commands Overview
-----------------
The git commands can helpfully be split into those that manipulate
@ -159,6 +166,9 @@ gitlink:git-merge-base[1]:: @@ -159,6 +166,9 @@ gitlink:git-merge-base[1]::
gitlink:git-name-rev[1]::
Find symbolic names for given revs.

gitlink:git-pack-redundant[1]::
Find redundant pack files.

gitlink:git-rev-list[1]::
Lists commit objects in reverse chronological order.

@ -211,6 +221,9 @@ gitlink:git-receive-pack[1]:: @@ -211,6 +221,9 @@ gitlink:git-receive-pack[1]::
gitlink:git-send-pack[1]::
Pushes to a remote repository, intelligently.

gitlink:git-http-push[1]::
Push missing objects using HTTP/DAV.

gitlink:git-shell[1]::
Restricted shell for GIT-only SSH access.

@ -340,6 +353,9 @@ gitlink:git-convert-objects[1]:: @@ -340,6 +353,9 @@ gitlink:git-convert-objects[1]::
gitlink:git-cvsimport[1]::
Salvage your data out of another SCM people love to hate.

gitlink:git-cvsexportcommit[1]::
Export a single commit to a CVS checkout.

gitlink:git-lost-found[1]::
Recover lost refs that luckily have not yet been pruned.

@ -573,14 +589,16 @@ include::../README[] @@ -573,14 +589,16 @@ include::../README[]

Authors
-------
git's founding father is Linus Torvalds <torvalds@osdl.org>.
The current git nurse is Junio C Hamano <junkio@cox.net>.
The git potty was written by Andres Ericsson <ae@op5.se>.
General upbringing is handled by the git-list <git@vger.kernel.org>.
* git's founding father is Linus Torvalds <torvalds@osdl.org>.
* The current git nurse is Junio C Hamano <junkio@cox.net>.
* The git potty was written by Andres Ericsson <ae@op5.se>.
* General upbringing is handled by the git-list <git@vger.kernel.org>.

Documentation
--------------
Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel.org>.
The documentation for git suite was started by David Greaves
<david@dgreaves.com>, and later enhanced greatly by the
contributors on the git-list <git@vger.kernel.org>.

GIT
---

7
Documentation/howto/using-topic-branches.txt

@ -31,7 +31,7 @@ test tree and then pull to the release tree as that would leave trivial @@ -31,7 +31,7 @@ test tree and then pull to the release tree as that would leave trivial
patches blocked in the test tree waiting for complex changes to accumulate
enough test time to graduate.

Back in the BitKeeper days I achieved this my creating small forests of
Back in the BitKeeper days I achieved this by creating small forests of
temporary trees, one tree for each logical grouping of patches, and then
pulling changes from these trees first to the test tree, and then to the
release tree. At first I replicated this in GIT, but then I realised
@ -42,7 +42,8 @@ So here is the step-by-step guide how this all works for me. @@ -42,7 +42,8 @@ So here is the step-by-step guide how this all works for me.

First create your work tree by cloning Linus's public tree:

$ git clone rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git work
$ git clone \
master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6.git work

Change directory into the cloned tree you just created

@ -52,7 +53,7 @@ Set up a remotes file so that you can fetch the latest from Linus' master @@ -52,7 +53,7 @@ Set up a remotes file so that you can fetch the latest from Linus' master
branch into a local branch named "linus":

$ cat > .git/remotes/linus
URL: rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
URL: master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Pull: master:linus
^D


3
Documentation/pack-protocol.txt → Documentation/technical/pack-protocol.txt

@ -1,3 +1,6 @@ @@ -1,3 +1,6 @@
Pack transfer protocols
=======================

There are two Pack push-pull protocols.

upload-pack (S) | fetch/clone-pack (C) protocol:

20
Documentation/tutorial.txt

@ -18,7 +18,14 @@ doing. @@ -18,7 +18,14 @@ doing.
The core git is often called "plumbing", with the prettier user
interfaces on top of it called "porcelain". You may not want to use the
plumbing directly very often, but it can be good to know what the
plumbing does for when the porcelain isn't flushing...
plumbing does for when the porcelain isn't flushing.

The material presented here often goes deep describing how things
work internally. If you are mostly interested in using git as a
SCM, you can skip them during your first pass.

[NOTE]
And those "too deep" descriptions are often marked as Note.


Creating a git repository
@ -252,6 +259,17 @@ tree. That's very useful. @@ -252,6 +259,17 @@ tree. That's very useful.
A common shorthand for `git-diff-files -p` is to just write `git
diff`, which will do the same thing.

------------
$ git diff
diff --git a/hello b/hello
index 557db03..263414f 100644
--- a/hello
+++ b/hello
@@ -1 +1,2 @@
Hello World
+It's a new day for git
------------


Committing git state
--------------------

4
Makefile

@ -55,7 +55,7 @@ all: @@ -55,7 +55,7 @@ all:
# Define USE_STDEV below if you want git to care about the underlying device
# change being considered an inode change from the update-cache perspective.

GIT_VERSION = 0.99.9m
GIT_VERSION = 0.99.9n

# CFLAGS and LDFLAGS are for the users to override from the command line.

@ -449,7 +449,7 @@ test-delta$X: test-delta.c diff-delta.o patch-delta.o @@ -449,7 +449,7 @@ test-delta$X: test-delta.c diff-delta.o patch-delta.o
$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $^

check:
for i in *.c; do sparse $(ALL_CFLAGS) $(SPARSE_FLAGS) $$i; done
for i in *.c; do sparse $(ALL_CFLAGS) $(SPARSE_FLAGS) $$i || exit; done




2
checkout-index.c

@ -58,7 +58,7 @@ static int checkout_file(const char *name) @@ -58,7 +58,7 @@ static int checkout_file(const char *name)

while (pos < active_nr) {
struct cache_entry *ce = active_cache[pos];
if (ce_namelen(ce) != namelen &&
if (ce_namelen(ce) != namelen ||
memcmp(ce->name, name, namelen))
break;
has_same_name = 1;

6
debian/changelog vendored

@ -1,3 +1,9 @@ @@ -1,3 +1,9 @@
git-core (0.99.9n-0) unstable; urgency=low

* GIT 0.99.9n aka 1.0rc6

-- Junio C Hamano <junkio@cox.net> Wed, 14 Dec 2005 17:27:08 -0800

git-core (0.99.9m-0) unstable; urgency=low

* GIT 0.99.9m aka 1.0rc5

7
diffcore-break.c

@ -62,10 +62,14 @@ static int should_break(struct diff_filespec *src, @@ -62,10 +62,14 @@ static int should_break(struct diff_filespec *src,
return 0; /* error but caught downstream */

base_size = ((src->size < dst->size) ? src->size : dst->size);
if (base_size < MINIMUM_BREAK_SIZE)
return 0; /* we do not break too small filepair */

delta = diff_delta(src->data, src->size,
dst->data, dst->size,
&delta_size, 0);
if (!delta)
return 0; /* error but caught downstream */

/* Estimate the edit size by interpreting delta. */
if (count_delta(delta, delta_size,
@ -168,8 +172,7 @@ void diffcore_break(int break_score) @@ -168,8 +172,7 @@ void diffcore_break(int break_score)
!S_ISDIR(p->one->mode) && !S_ISDIR(p->two->mode) &&
!strcmp(p->one->path, p->two->path)) {
if (should_break(p->one, p->two,
break_score, &score) &&
MINIMUM_BREAK_SIZE <= p->one->size) {
break_score, &score)) {
/* Split this into delete and create */
struct diff_filespec *null_one, *null_two;
struct diff_filepair *dp;

13
git-add.sh

@ -1,13 +1,8 @@ @@ -1,13 +1,8 @@
#!/bin/sh

die () {
echo >&2 "$*"
exit 1
}

usage() {
die "usage: git add [-n] [-v] <file>..."
}
USAGE='[-n] [-v] <file>...'
SUBDIRECTORY_OK='Yes'
. git-sh-setup

show_only=
verbose=
@ -29,8 +24,6 @@ while : ; do @@ -29,8 +24,6 @@ while : ; do
shift
done

GIT_DIR=$(git-rev-parse --git-dir) || exit

if test -f "$GIT_DIR/info/exclude"
then
git-ls-files -z \

22
git-am.sh

@ -1,14 +1,10 @@ @@ -1,14 +1,10 @@
#!/bin/sh
#
#
. git-sh-setup

usage () {
echo >&2 "usage: $0 [--signoff] [--dotest=<dir>] [--utf8] [--binary] [--3way] <mbox>"
echo >&2 " or, when resuming"
echo >&2 " $0 [--skip | --resolved]"
exit 1;
}
USAGE='[--signoff] [--dotest=<dir>] [--utf8] [--binary] [--3way] <mbox>
or, when resuming [--skip | --resolved]'
. git-sh-setup

stop_here () {
echo "$1" >"$dotest/next"
@ -164,10 +160,7 @@ else @@ -164,10 +160,7 @@ else
# Start afresh.
mkdir -p "$dotest" || exit

# cat does the right thing for us, including '-' to mean
# standard input.
cat "$@" |
git-mailsplit -d$prec "$dotest/" >"$dotest/last" || {
git-mailsplit -d"$prec" -o"$dotest" -b -- "$@" > "$dotest/last" || {
rm -fr "$dotest"
exit 1
}
@ -256,6 +249,13 @@ do @@ -256,6 +249,13 @@ do
GIT_AUTHOR_NAME="$(sed -n '/^Author/ s/Author: //p' "$dotest/info")"
GIT_AUTHOR_EMAIL="$(sed -n '/^Email/ s/Email: //p' "$dotest/info")"
GIT_AUTHOR_DATE="$(sed -n '/^Date/ s/Date: //p' "$dotest/info")"

if test -z "$GIT_AUTHOR_EMAIL"
then
echo "Patch does not have a valid e-mail address."
stop_here $this
fi

export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE

SUBJECT="$(sed -n '/^Subject/ s/Subject: //p' "$dotest/info")"

6
git-applymbox.sh

@ -18,13 +18,9 @@ @@ -18,13 +18,9 @@
##
## git-am is supposed to be the newer and better tool for this job.

USAGE='[-u] [-k] [-q] [-m] (-c .dotest/<num> | mbox) [signoff]'
. git-sh-setup

usage () {
echo >&2 "applymbox [-u] [-k] [-q] [-m] (-c .dotest/<num> | mbox) [signoff]"
exit 1
}

keep_subject= query_apply= continue= utf8= resume=t
while case "$#" in 0) break ;; esac
do

4
git-applypatch.sh

@ -10,8 +10,12 @@ @@ -10,8 +10,12 @@
## $3 - "info" file with Author, email and subject
## $4 - optional file containing signoff to add
##

USAGE='<msg> <patch> <info> [<signoff>]'
. git-sh-setup

case "$#" in 3|4) usage ;; esac

final=.dotest/final-commit
##
## If this file exists, we ask before applying

24
git-bisect.sh

@ -1,4 +1,15 @@ @@ -1,4 +1,15 @@
#!/bin/sh

USAGE='[start|bad|good|next|reset|visualize]'
LONG_USAGE='git bisect start [<pathspec>] reset bisect state and start bisection.
git bisect bad [<rev>] mark <rev> a known-bad revision.
git bisect good [<rev>...] mark <rev>... known-good revisions.
git bisect next find next bisection to test and check it out.
git bisect reset [<branch>] finish bisection search and go back to branch.
git bisect visualize show bisect status in gitk.
git bisect replay <logfile> replay bisection log
git bisect log show bisect log.'

. git-sh-setup

sq() {
@ -11,19 +22,6 @@ sq() { @@ -11,19 +22,6 @@ sq() {
' "$@"
}

usage() {
echo >&2 'usage: git bisect [start|bad|good|next|reset|visualize]
git bisect start [<pathspec>] reset bisect state and start bisection.
git bisect bad [<rev>] mark <rev> a known-bad revision.
git bisect good [<rev>...] mark <rev>... known-good revisions.
git bisect next find next bisection to test and check it out.
git bisect reset [<branch>] finish bisection search and go back to branch.
git bisect visualize show bisect status in gitk.
git bisect replay <logfile> replay bisection log
git bisect log show bisect log.'
exit 1
}

bisect_autostart() {
test -d "$GIT_DIR/refs/bisect" || {
echo >&2 'You need to start by "git bisect start"'

21
git-branch.sh

@ -1,21 +1,12 @@ @@ -1,21 +1,12 @@
#!/bin/sh

GIT_DIR=`git-rev-parse --git-dir` || exit $?

die () {
echo >&2 "$*"
exit 1
}

usage () {
echo >&2 "usage: $(basename $0)"' [-d <branch>] | [[-f] <branch> [start-point]]

If no arguments, show available branches and mark current branch with a star.
USAGE='[-d <branch>] | [[-f] <branch> [start-point]]'
LONG_USAGE='If no arguments, show available branches and mark current branch with a star.
If one argument, create a new branch <branchname> based off of current HEAD.
If two arguments, create a new branch <branchname> based off of <start-point>.
'
exit 1
}
If two arguments, create a new branch <branchname> based off of <start-point>.'

SUBDIRECTORY_OK='Yes'
. git-sh-setup

headref=$(git-symbolic-ref HEAD | sed -e 's|^refs/heads/||')


6
git-checkout.sh

@ -1,9 +1,7 @@ @@ -1,9 +1,7 @@
#!/bin/sh
. git-sh-setup

usage () {
die "usage: git checkout [-f] [-b <new_branch>] [<branch>] [<paths>...]"
}
USAGE='[-f] [-b <new_branch>] [<branch>] [<paths>...]'
. git-sh-setup

old=$(git-rev-parse HEAD)
new=

13
git-cherry.sh

@ -3,11 +3,8 @@ @@ -3,11 +3,8 @@
# Copyright (c) 2005 Junio C Hamano.
#

. git-sh-setup

usage="usage: $0 "'[-v] <upstream> [<head>]

__*__*__*__*__> <upstream>
USAGE='[-v] <upstream> [<head>]'
LONG_USAGE=' __*__*__*__*__> <upstream>
/
fork-point
\__+__+__+__+__+__+__+__> <head>
@ -16,8 +13,8 @@ Each commit between the fork-point and <head> is examined, and @@ -16,8 +13,8 @@ Each commit between the fork-point and <head> is examined, and
compared against the change each commit between the fork-point and
<upstream> introduces. If the change seems to be in the upstream,
it is shown on the standard output with prefix "+". Otherwise
it is shown with prefix "-".
'
it is shown with prefix "-".'
. git-sh-setup

case "$1" in -v) verbose=t; shift ;; esac

@ -35,7 +32,7 @@ case "$#" in @@ -35,7 +32,7 @@ case "$#" in
2) upstream=`git-rev-parse --verify "$1"` &&
ours=`git-rev-parse --verify "$2"` || exit
;;
*) echo >&2 "$usage"; exit 1 ;;
*) usage ;;
esac

# Note that these list commits in reverse order;

7
git-clone.sh

@ -9,7 +9,7 @@ @@ -9,7 +9,7 @@
unset CDPATH

usage() {
echo >&2 "* git clone [-l [-s]] [-q] [-u <upload-pack>] [-n] <repo> [<dir>]"
echo >&2 "Usage: $0 [-l [-s]] [-q] [-u <upload-pack>] [-n] <repo> [<dir>]"
exit 1
}

@ -188,7 +188,10 @@ yes,yes) @@ -188,7 +188,10 @@ yes,yes)
cd "$D" && case "$upload_pack" in
'') git-clone-pack $quiet "$repo" ;;
*) git-clone-pack $quiet "$upload_pack" "$repo" ;;
esac
esac || {
echo >&2 "clone-pack from '$repo' failed."
exit 1
}
;;
esac
;;

5
git-commit.sh

@ -3,12 +3,9 @@ @@ -3,12 +3,9 @@
# Copyright (c) 2005 Linus Torvalds
#

USAGE='[-a] [-s] [-v | --no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit>] [-e] [<path>...]'
. git-sh-setup

usage () {
die 'git commit [-a] [-s] [-v | --no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit>] [-e] [<path>...]'
}

all= logfile= use_commit= no_edit= log_given= log_message= verify=t signoff=
while case "$#" in 0) break;; esac
do

3
git-compat-util.h

@ -110,4 +110,7 @@ static inline int sane_case(int x, int high) @@ -110,4 +110,7 @@ static inline int sane_case(int x, int high)
return x;
}

#ifndef MAXPATHLEN
#define MAXPATHLEN 256
#endif
#endif

5
git-fetch.sh

@ -1,5 +1,7 @@ @@ -1,5 +1,7 @@
#!/bin/sh
#

USAGE='<fetch-options> <repository> <refspec>...'
. git-sh-setup
. git-parse-remote
_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
@ -34,6 +36,9 @@ do @@ -34,6 +36,9 @@ do
-v|--verbose)
verbose=Yes
;;
-*)
usage
;;
*)
break
;;

25
git-format-patch.sh

@ -3,19 +3,8 @@ @@ -3,19 +3,8 @@
# Copyright (c) 2005 Junio C Hamano
#

. git-sh-setup

# Force diff to run in C locale.
LANG=C LC_ALL=C
export LANG LC_ALL

usage () {
echo >&2 "usage: $0"' [-n] [-o dir | --stdout] [--keep-subject] [--mbox]
[--check] [--signoff] [-<diff options>...]
[--help]
( from..to ... | upstream [ our-head ] )

Prepare each commit with its patch since our-head forked from upstream,
USAGE='[-n | -k] [-o <dir> | --stdout] [--signoff] [--check] [--mbox] [--diff-options] <upstream> [<our-head>]'
LONG_USAGE='Prepare each commit with its patch since our-head forked from upstream,
one file per patch, for e-mail submission. Each output file is
numbered sequentially from 1, and uses the first line of the commit
message (massaged for pathname safety) as the filename.
@ -28,10 +17,12 @@ as "[PATCH N/M] Subject", unless you have only one patch. @@ -28,10 +17,12 @@ as "[PATCH N/M] Subject", unless you have only one patch.

When --mbox is specified, the output is formatted to resemble
UNIX mailbox format, and can be concatenated together for processing
with applymbox.
'
exit 1
}
with applymbox.'
. git-sh-setup

# Force diff to run in C locale.
LANG=C LC_ALL=C
export LANG LC_ALL

diff_opts=
LF='

7
git-grep.sh

@ -3,6 +3,10 @@ @@ -3,6 +3,10 @@
# Copyright (c) Linus Torvalds, 2005
#

USAGE='<option>... <pattern> <path>...'
SUBDIRECTORY_OK='Yes'
. git-sh-setup

pattern=
flags=()
git_flags=()
@ -40,8 +44,7 @@ while : ; do @@ -40,8 +44,7 @@ while : ; do
shift
done
[ "$pattern" ] || {
echo >&2 "usage: 'git grep <pattern> [pathspec*]'"
exit 1
usage
}
git-ls-files -z "${git_flags[@]}" "$@" |
xargs -0 grep "${flags[@]}" -e "$pattern"

10
git-lost-found.sh

@ -1,6 +1,14 @@ @@ -1,6 +1,14 @@
#!/bin/sh

GIT_DIR=`git-rev-parse --git-dir` || exit $?
USAGE=''
SUBDIRECTORY_OK='Yes'
. git-sh-setup

if [ "$#" != "0" ]
then
usage
fi

laf="$GIT_DIR/lost-found"
rm -fr "$laf" && mkdir -p "$laf/commit" "$laf/other" || exit


11
git-merge.sh

@ -3,15 +3,13 @@ @@ -3,15 +3,13 @@
# Copyright (c) 2005 Junio C Hamano
#


USAGE='[-n] [--no-commit] [-s <strategy>]... <merge-message> <head> <remote>+'
. git-sh-setup

LF='
'

usage () {
die "git-merge [-n] [--no-commit] [-s <strategy>]... <merge-message> <head> <remote>+"
}

all_strategies='recursive octopus resolve stupid ours'
default_strategies='recursive'
use_strategies=
@ -97,11 +95,14 @@ head=$(git-rev-parse --verify "$1"^0) || usage @@ -97,11 +95,14 @@ head=$(git-rev-parse --verify "$1"^0) || usage
shift

# All the rest are remote heads
remoteheads=
for remote
do
git-rev-parse --verify "$remote"^0 >/dev/null ||
remotehead=$(git-rev-parse --verify "$remote"^0) ||
die "$remote - not something we can merge"
remoteheads="${remoteheads}$remotehead "
done
set x $remoteheads ; shift

case "$#" in
1)

3
git-prune.sh

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
#!/bin/sh

USAGE='[-n] [--] [<head>...]'
. git-sh-setup

dryrun=
@ -9,7 +10,7 @@ do @@ -9,7 +10,7 @@ do
case "$1" in
-n) dryrun=-n echo=echo ;;
--) break ;;
-*) echo >&2 "usage: git-prune [ -n ] [ heads... ]"; exit 1 ;;
-*) usage ;;
*) break ;;
esac
shift;

13
git-pull.sh

@ -4,19 +4,10 @@ @@ -4,19 +4,10 @@
#
# Fetch one or more remote refs and merge it/them into the current HEAD.

USAGE='[-n | --no-summary] [--no-commit] [-s strategy]... [<fetch-options>] <repo> <head>...'
LONG_USAGE='Fetch one or more remote refs and merge it/them into the current HEAD.'
. git-sh-setup

usage () {
echo >&2 "usage: $0"' [-n] [--no-commit] [--no-summary] [--help]
[-s strategy]...
[<fetch-options>]
<repo> <head>...

Fetch one or more remote refs and merge it/them into the current HEAD.
'
exit 1
}

strategy_args= no_summary= no_commit=
while case "$#,$1" in 0) break ;; *,-*) ;; *) break ;; esac
do

7
git-push.sh

@ -1,10 +1,7 @@ @@ -1,10 +1,7 @@
#!/bin/sh
. git-sh-setup

usage () {
die "Usage: git push [--all] [--force] <repository> [<refspec>]"
}

USAGE='[--all] [--force] <repository> [<refspec>...]'
. git-sh-setup

# Parse out parameters and then stop at remote, so that we can
# translate it using .git/branches information

33
git-rebase.sh

@ -3,8 +3,11 @@ @@ -3,8 +3,11 @@
# Copyright (c) 2005 Junio C Hamano.
#

USAGE='<upstream> [<head>]'
. git-sh-setup

case $# in 1|2) ;; *) usage ;; esac

# Make sure we do not have .dotest
if mkdir .dotest
then
@ -18,31 +21,30 @@ you still have something valuable there.' @@ -18,31 +21,30 @@ you still have something valuable there.'
exit 1
fi

# The other head is given. Make sure it is valid.
other=$(git-rev-parse --verify "$1^0") || exit

# Make sure we have HEAD that is valid.
head=$(git-rev-parse --verify "HEAD^0") || exit

# The tree must be really really clean.
git-update-index --refresh || exit
diff=$(git-diff-index --cached --name-status -r HEAD)
case "$different" in
case "$diff" in
?*) echo "$diff"
exit 1
;;
esac

# The other head is given. Make sure it is valid.
other=$(git-rev-parse --verify "$1^0") || usage

# Make sure the branch to rebase is valid.
head=$(git-rev-parse --verify "${2-HEAD}^0") || exit

# If the branch to rebase is given, first switch to it.
case "$#" in
2)
git-checkout "$2" || exit
git-checkout "$2" || usage
esac

# If the HEAD is a proper descendant of $other, we do not even need
# to rebase. Make sure we do not do needless rebase. In such a
# case, merge-base should be the same as "$other".
mb=$(git-merge-base "$other" "$head")

# Check if we are already based on $other.
if test "$mb" = "$other"
then
echo >&2 "Current branch `git-symbolic-ref HEAD` is up to date."
@ -51,5 +53,14 @@ fi @@ -51,5 +53,14 @@ fi

# Rewind the head to "$other"
git-reset --hard "$other"

# If the $other is a proper descendant of the tip of the branch, then
# we just fast forwarded.
if test "$mb" = "$head"
then
echo >&2 "Fast-forwarded $head to $other."
exit 0
fi

git-format-patch -k --stdout --full-index "$other" ORIG_HEAD |
git am --binary -3 -k

3
git-repack.sh

@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
# Copyright (c) 2005 Linus Torvalds
#

USAGE='[-a] [-d] [-l] [-n]'
. git-sh-setup
no_update_info= all_into_one= remove_redundant= local=
@ -13,7 +14,7 @@ do @@ -13,7 +14,7 @@ do
-a) all_into_one=t ;;
-d) remove_redundant=t ;;
-l) local=t ;;
*) break ;;
*) usage ;;
esac
shift
done

12
git-request-pull.sh

@ -4,13 +4,11 @@ @@ -4,13 +4,11 @@
# This file is licensed under the GPL v2, or a later version
# at the discretion of Linus Torvalds.

usage()
{
echo "$0 <commit> <url> [ <head> ]"
echo " Summarizes the changes since <commit> to the standard output,"
echo " and includes <url> in the message generated."
exit 1
}
USAGE='<commit> <url> [<head>]'
LONG_USAGE='Summarizes the changes since <commit> to the standard output,
and includes <url> in the message generated.'
SUBDIRECTORY_OK='Yes'
. git-sh-setup

revision=$1
url=$2

6
git-reset.sh

@ -1,9 +1,7 @@ @@ -1,9 +1,7 @@
#!/bin/sh
. git-sh-setup

usage () {
die 'Usage: git reset [--mixed | --soft | --hard] [<commit-ish>]'
}
USAGE='[--mixed | --soft | --hard] [<commit-ish>]'
. git-sh-setup

tmp=/var/tmp/reset.$$
trap 'rm -f $tmp-*' 0 1 2 3 15

6
git-resolve.sh

@ -4,11 +4,9 @@ @@ -4,11 +4,9 @@
#
# Resolve two trees.
#
. git-sh-setup

usage () {
die "git-resolve <head> <remote> <merge-message>"
}
USAGE='<head> <remote> <merge-message>'
. git-sh-setup

dropheads() {
rm -f -- "$GIT_DIR/MERGE_HEAD" \

19
git-revert.sh

@ -3,29 +3,20 @@ @@ -3,29 +3,20 @@
# Copyright (c) 2005 Linus Torvalds
# Copyright (c) 2005 Junio C Hamano
#
. git-sh-setup

case "$0" in
*-revert* )
test -t 0 && edit=-e
me=revert ;;
me=revert
USAGE='[--edit | --no-edit] [-n] <commit-ish>' ;;
*-cherry-pick* )
edit=
me=cherry-pick ;;
me=cherry-pick
USAGE='[--edit] [-n] [-r] <commit-ish>' ;;
* )
die "What are you talking about?" ;;
esac

usage () {
case "$me" in
cherry-pick)
die "usage git $me [--edit] [-n] [-r] <commit-ish>"
;;
revert)
die "usage git $me [--edit | --no-edit] [-n] <commit-ish>"
;;
esac
}
. git-sh-setup

no_commit= replay=
while case "$#" in 0) break ;; esac

34
git-sh-setup.sh

@ -11,13 +11,37 @@ @@ -11,13 +11,37 @@
# exporting it.
unset CDPATH

: ${GIT_DIR=.git}
: ${GIT_OBJECT_DIRECTORY="$GIT_DIR/objects"}

die() {
echo >&2 "$@"
exit 1
}

# Make sure we are in a valid repository of a vintage we understand.
GIT_DIR="$GIT_DIR" git-var GIT_AUTHOR_IDENT >/dev/null || exit
usage() {
die "Usage: $0 $USAGE"
}

if [ -z "$LONG_USAGE" ]
then
LONG_USAGE="Usage: $0 $USAGE"
else
LONG_USAGE="Usage: $0 $USAGE

$LONG_USAGE"
fi

case "$1" in
--h|--he|--hel|--help)
echo "$LONG_USAGE"
exit
esac

if [ -z "$SUBDIRECTORY_OK" ]
then
: ${GIT_DIR=.git}
: ${GIT_OBJECT_DIRECTORY="$GIT_DIR/objects"}

# Make sure we are in a valid repository of a vintage we understand.
GIT_DIR="$GIT_DIR" git-var GIT_AUTHOR_IDENT >/dev/null || exit
else
GIT_DIR=$(git-rev-parse --git-dir) || exit
fi

11
git-status.sh

@ -2,7 +2,16 @@ @@ -2,7 +2,16 @@
#
# Copyright (c) 2005 Linus Torvalds
#
GIT_DIR=$(git-rev-parse --git-dir) || exit

USAGE=''
SUBDIRECTORY_OK='Yes'

. git-sh-setup

if [ "$#" != "0" ]
then
usage
fi

report () {
header="#

14
git-tag.sh

@ -1,17 +1,9 @@ @@ -1,17 +1,9 @@
#!/bin/sh
# Copyright (c) 2005 Linus Torvalds

GIT_DIR=`git-rev-parse --git-dir` || exit $?

usage () {
echo >&2 "Usage: git-tag [-a | -s | -u <key-id>] [-f | -d] [-m <msg>] <tagname> [<head>]"
exit 1
}

die () {
echo >&2 "$*"
exit 1
}
USAGE='[-a | -s | -u <key-id>] [-f | -d] [-m <msg>] <tagname> [<head>]'
SUBDIRECTORY_OK='Yes'
. git-sh-setup

annotate=
signed=

12
git-verify-tag.sh

@ -1,11 +1,13 @@ @@ -1,11 +1,13 @@
#!/bin/sh

GIT_DIR=`git-rev-parse --git-dir` || exit $?
USAGE='<tag>'
SUBDIRECTORY_OK='Yes'
. git-sh-setup

die () {
echo >&2 "$*"
exit 1
}
if [ "$#" != "1" ]
then
usage
fi

type="$(git-cat-file -t "$1" 2>/dev/null)" ||
die "$1: no such object."

32
mailinfo.c

@ -40,13 +40,43 @@ static char *sanity_check(char *name, char *email) @@ -40,13 +40,43 @@ static char *sanity_check(char *name, char *email)
return name;
}

static int bogus_from(char *line)
{
/* John Doe <johndoe> */
char *bra, *ket, *dst, *cp;

/* This is fallback, so do not bother if we already have an
* e-mail address.
*/
if (*email)
return 0;

bra = strchr(line, '<');
if (!bra)
return 0;
ket = strchr(bra, '>');
if (!ket)
return 0;

for (dst = email, cp = bra+1; cp < ket; )
*dst++ = *cp++;
*dst = 0;
for (cp = line; isspace(*cp); cp++)
;
for (bra--; isspace(*bra); bra--)
*bra = 0;
cp = sanity_check(cp, email);
strcpy(name, cp);
return 1;
}

static int handle_from(char *line)
{
char *at = strchr(line, '@');
char *dst;

if (!at)
return 0;
return bogus_from(line);

/*
* If we already have one email, don't take any confusing lines

91
mailsplit.c

@ -15,7 +15,7 @@ @@ -15,7 +15,7 @@
#include "cache.h"

static const char git_mailsplit_usage[] =
"git-mailsplit [-d<prec>] [<mbox>] <directory>";
"git-mailsplit [-d<prec>] [-f<n>] [-b] -o<directory> <mbox>...";

static int is_from_line(const char *line, int len)
{
@ -56,14 +56,15 @@ static char buf[4096]; @@ -56,14 +56,15 @@ static char buf[4096];
* the Unix "From " line. Write it into the specified
* file.
*/
static int split_one(FILE *mbox, const char *name)
static int split_one(FILE *mbox, const char *name, int allow_bare)
{
FILE *output = NULL;
int len = strlen(buf);
int fd;
int status = 0;
int is_bare = !is_from_line(buf, len);

if (!is_from_line(buf, len))
if (is_bare && !allow_bare)
goto corrupt;

fd = open(name, O_WRONLY | O_CREAT | O_EXCL, 0666);
@ -88,7 +89,7 @@ static int split_one(FILE *mbox, const char *name) @@ -88,7 +89,7 @@ static int split_one(FILE *mbox, const char *name)
die("cannot read mbox");
}
len = strlen(buf);
if (!is_partial && is_from_line(buf, len))
if (!is_partial && !is_bare && is_from_line(buf, len))
break; /* done with one message */
}
fclose(output);
@ -104,54 +105,82 @@ static int split_one(FILE *mbox, const char *name) @@ -104,54 +105,82 @@ static int split_one(FILE *mbox, const char *name)

int main(int argc, const char **argv)
{
int i, nr, nr_prec = 4;
FILE *mbox = NULL;
int nr = 0, nr_prec = 4;
int allow_bare = 0;
const char *dir = NULL;
const char **argp;
static const char *stdin_only[] = { "-", NULL };
char *name;

for (i = 1; i < argc; i++) {
const char *arg = argv[i];
for (argp = argv+1; *argp; argp++) {
const char *arg = *argp;

if (arg[0] != '-')
break;
/* do flags here */
if (!strncmp(arg, "-d", 2)) {
nr_prec = strtol(arg + 2, NULL, 10);
if ( arg[1] == 'd' ) {
nr_prec = strtol(arg+2, NULL, 10);
if (nr_prec < 3 || 10 <= nr_prec)
usage(git_mailsplit_usage);
continue;
} else if ( arg[1] == 'f' ) {
nr = strtol(arg+2, NULL, 10);
} else if ( arg[1] == 'b' && !arg[2] ) {
allow_bare = 1;
} else if ( arg[1] == 'o' && arg[2] ) {
dir = arg+2;
} else if ( arg[1] == '-' && !arg[2] ) {
argp++; /* -- marks end of options */
break;
} else {
die("unknown option: %s", arg);
}
}

/* Either one remaining arg (dir), or two (mbox and dir) */
switch (argc - i) {
if ( !dir ) {
/* Backwards compatibility: if no -o specified, accept
<mbox> <dir> or just <dir> */
switch (argc - (argp-argv)) {
case 1:
mbox = stdin;
dir = argp[0];
argp = stdin_only;
break;
case 2:
if ((mbox = fopen(argv[i], "r")) == NULL)
die("cannot open mbox %s for reading", argv[i]);
stdin_only[0] = argp[0];
dir = argp[1];
argp = stdin_only;
break;
default:
usage(git_mailsplit_usage);
}
if (chdir(argv[argc - 1]) < 0)
usage(git_mailsplit_usage);
} else {
/* New usage: if no more argument, parse stdin */
if ( !*argp )
argp = stdin_only;
}

nr = 0;
if (fgets(buf, sizeof(buf), mbox) == NULL)
die("cannot read mbox");
name = xmalloc(strlen(dir) + 2 + 3 * sizeof(nr));

for (;;) {
char name[10];
while (*argp) {
const char *file = *argp++;
FILE *f = !strcmp(file, "-") ? stdin : fopen(file, "rt");
int file_done = 0;

sprintf(name, "%0*d", nr_prec, ++nr);
switch (split_one(mbox, name)) {
case 0:
break;
case 1:
printf("%d\n", nr);
return 0;
default:
exit(1);
if ( !f )
die ("cannot open mbox %s", file);

if (fgets(buf, sizeof(buf), f) == NULL)
die("cannot read mbox %s", file);

while (!file_done) {
sprintf(name, "%s/%0*d", dir, nr_prec, ++nr);
file_done = split_one(f, name, allow_bare);
}

if (f != stdin)
fclose(f);
}

printf("%d\n", nr);
return 0;
}

6
send-pack.c

@ -179,6 +179,7 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec) @@ -179,6 +179,7 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)
{
struct ref *ref;
int new_refs;
int ret = 0;

/* No funny business with the matcher */
remote_tail = get_remote_heads(in, &remote_refs, 0, NULL, 1);
@ -232,6 +233,7 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec) @@ -232,6 +233,7 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)
error("remote '%s' object %s does not "
"exist on local",
ref->name, sha1_to_hex(ref->old_sha1));
ret = -2;
continue;
}

@ -245,12 +247,14 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec) @@ -245,12 +247,14 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)
error("remote ref '%s' is not a strict "
"subset of local ref '%s'.", ref->name,
ref->peer_ref->name);
ret = -2;
continue;
}
}
memcpy(ref->new_sha1, ref->peer_ref->new_sha1, 20);
if (is_zero_sha1(ref->new_sha1)) {
error("cannot happen anymore");
ret = -3;
continue;
}
new_refs++;
@ -267,7 +271,7 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec) @@ -267,7 +271,7 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)
if (new_refs)
pack_objects(out, remote_refs);
close(out);
return 0;
return ret;
}



4
t/t3200-branch.sh

@ -16,8 +16,8 @@ test_expect_success \ @@ -16,8 +16,8 @@ test_expect_success \
git-update-index --add A &&
git-commit -m "Initial commit."'

test_expect_failure \
'git branch --help should return error code' \
test_expect_success \
'git branch --help should return success now.' \
'git-branch --help'

test_expect_failure \

34
t/t3400-rebase.sh

@ -0,0 +1,34 @@ @@ -0,0 +1,34 @@
#!/bin/sh
#
# Copyright (c) 2005 Amos Waterland
#

test_description='git rebase should not destroy author information

This test runs git rebase and checks that the author information is not lost.
'
. ./test-lib.sh

export GIT_AUTHOR_EMAIL=bogus_email_address

test_expect_success \
'prepare repository with topic branch, then rebase against master' \
'echo First > A &&
git-update-index --add A &&
git-commit -m "Add A." &&
git checkout -b my-topic-branch &&
echo Second > B &&
git-update-index --add B &&
git-commit -m "Add B." &&
git checkout -f master &&
echo Third >> A &&
git-update-index A &&
git-commit -m "Modify A." &&
git checkout -f my-topic-branch &&
git rebase master'

test_expect_failure \
'the rebase operation should not have destroyed author information' \
'git log | grep "Author:" | grep "<>"'

test_done

10
t/t5400-send-pack.sh

@ -43,7 +43,15 @@ test_expect_success setup ' @@ -43,7 +43,15 @@ test_expect_success setup '
test_expect_success \
'pushing rewound head should not barf but require --force' '
# should not fail but refuse to update.
git-send-pack ./victim/.git/ master &&
if git-send-pack ./victim/.git/ master
then
# now it should fail with Pasky patch
echo >&2 Gaah, it should have failed.
false
else
echo >&2 Thanks, it correctly failed.
true
fi &&
if cmp victim/.git/refs/heads/master .git/refs/heads/master
then
# should have been left as it was!

Loading…
Cancel
Save