summaryrefslogtreecommitdiff
path: root/Documentation/howto
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/howto')
-rw-r--r--Documentation/howto/dangling-objects.txt109
-rw-r--r--Documentation/howto/isolate-bugs-with-bisect.txt65
-rw-r--r--Documentation/howto/maintain-git.txt277
-rw-r--r--Documentation/howto/make-dist.txt52
-rw-r--r--Documentation/howto/rebase-and-edit.txt81
-rw-r--r--Documentation/howto/rebase-from-internal-branch.txt16
-rw-r--r--Documentation/howto/rebuild-from-update-hook.txt3
-rw-r--r--Documentation/howto/recover-corrupted-blob-object.txt134
-rw-r--r--Documentation/howto/revert-a-faulty-merge.txt179
-rw-r--r--Documentation/howto/revert-branch-rebase.txt4
-rw-r--r--Documentation/howto/separating-topic-branches.txt15
-rw-r--r--Documentation/howto/setup-git-server-over-http.txt47
-rw-r--r--Documentation/howto/update-hook-example.txt98
-rw-r--r--Documentation/howto/use-git-daemon.txt1
-rw-r--r--Documentation/howto/using-merge-subtree.txt75
-rw-r--r--Documentation/howto/using-topic-branches.txt296
16 files changed, 775 insertions, 677 deletions
diff --git a/Documentation/howto/dangling-objects.txt b/Documentation/howto/dangling-objects.txt
deleted file mode 100644
index e82ddae3cf..0000000000
--- a/Documentation/howto/dangling-objects.txt
+++ /dev/null
@@ -1,109 +0,0 @@
-From: Linus Torvalds <torvalds@linux-foundation.org>
-Subject: Re: Question about fsck-objects output
-Date: Thu, 25 Jan 2007 12:01:06 -0800 (PST)
-Message-ID: <Pine.LNX.4.64.0701251144290.25027@woody.linux-foundation.org>
-Archived-At: <http://permalink.gmane.org/gmane.comp.version-control.git/37754>
-Abstract: Linus describes what dangling objects are, when they
- are left behind, and how to view their relationship with branch
- heads in gitk
-
-On Thu, 25 Jan 2007, Larry Streepy wrote:
-
-> Sorry to ask such a basic question, but I can't quite decipher the output of
-> fsck-objects. When I run it, I get this:
->
-> git fsck-objects
-> dangling commit 2213f6d4dd39ca8baebd0427723723e63208521b
-> dangling commit f0d4e00196bd5ee54463e9ea7a0f0e8303da767f
-> dangling blob 6a6d0b01b3e96d49a8f2c7addd4ef8c3bd1f5761
->
->
-> Even after a "repack -a -d" they still exist. The man page has a short
-> explanation, but, at least for me, it wasn't fully enlightening. :-)
->
-> The man page says that dangling commits could be "root" commits, but since my
-> repo started as a clone of another repo, I don't see how I could have any root
-> commits. Also, the page doesn't really describe what a dangling blob is.
->
-> So, can someone explain what these artifacts are and if they are a problem
-> that I should be worried about?
-
-The most common situation is that you've rebased a branch (or you have
-pulled from somebody else who rebased a branch, like the "pu" branch in
-the git.git archive itself).
-
-What happens is that the old head of the original branch still exists, as
-does obviously everything it pointed to. The branch pointer itself just
-doesn't, since you replaced it with another one.
-
-However, there are certainly other situations too that cause dangling
-objects. For example, the "dangling blob" situation you have tends to be
-because you did a "git add" of a file, but then, before you actually
-committed it and made it part of the bigger picture, you changed something
-else in that file and committed that *updated* thing - the old state that
-you added originally ends up not being pointed to by any commit/tree, so
-it's now a dangling blob object.
-
-Similarly, when the "recursive" merge strategy runs, and finds that there
-are criss-cross merges and thus more than one merge base (which is fairly
-unusual, but it does happen), it will generate one temporary midway tree
-(or possibly even more, if you had lots of criss-crossing merges and
-more than two merge bases) as a temporary internal merge base, and again,
-those are real objects, but the end result will not end up pointing to
-them, so they end up "dangling" in your repository.
-
-Generally, dangling objects aren't anything to worry about. They can even
-be very useful: if you screw something up, the dangling objects can be how
-you recover your old tree (say, you did a rebase, and realized that you
-really didn't want to - you can look at what dangling objects you have,
-and decide to reset your head to some old dangling state).
-
-For commits, the most useful thing to do with dangling objects tends to be
-to do a simple
-
- gitk <dangling-commit-sha-goes-here> --not --all
-
-which means exactly what it sounds like: it says that you want to see the
-commit history that is described by the dangling commit(s), but you do NOT
-want to see the history that is described by all your branches and tags
-(which are the things you normally reach). That basically shows you in a
-nice way what the danglign commit was (and notice that it might not be
-just one commit: we only report the "tip of the line" as being dangling,
-but there might be a whole deep and complex commit history that has gotten
-dropped - rebasing will do that).
-
-For blobs and trees, you can't do the same, but you can examine them. You
-can just do
-
- git show <dangling-blob/tree-sha-goes-here>
-
-to show what the contents of the blob were (or, for a tree, basically what
-the "ls" for that directory was), and that may give you some idea of what
-the operation was that left that dangling object.
-
-Usually, dangling blobs and trees aren't very interesting. They're almost
-always the result of either being a half-way mergebase (the blob will
-often even have the conflict markers from a merge in it, if you have had
-conflicting merges that you fixed up by hand), or simply because you
-interrupted a "git fetch" with ^C or something like that, leaving _some_
-of the new objects in the object database, but just dangling and useless.
-
-Anyway, once you are sure that you're not interested in any dangling
-state, you can just prune all unreachable objects:
-
- git prune
-
-and they'll be gone. But you should only run "git prune" on a quiescent
-repository - it's kind of like doing a filesystem fsck recovery: you don't
-want to do that while the filesystem is mounted.
-
-(The same is true of "git-fsck-objects" itself, btw - but since
-git-fsck-objects never actually *changes* the repository, it just reports
-on what it found, git-fsck-objects itself is never "dangerous" to run.
-Running it while somebody is actually changing the repository can cause
-confusing and scary messages, but it won't actually do anything bad. In
-contrast, running "git prune" while somebody is actively changing the
-repository is a *BAD* idea).
-
- Linus
-
diff --git a/Documentation/howto/isolate-bugs-with-bisect.txt b/Documentation/howto/isolate-bugs-with-bisect.txt
deleted file mode 100644
index 926bbdc3cb..0000000000
--- a/Documentation/howto/isolate-bugs-with-bisect.txt
+++ /dev/null
@@ -1,65 +0,0 @@
-From: Linus Torvalds <torvalds () osdl ! org>
-To: git@vger.kernel.org
-Date: 2005-11-08 1:31:34
-Subject: Real-life kernel debugging scenario
-Abstract: Short-n-sweet, Linus tells us how to leverage `git-bisect` to perform
- bug isolation on a repository where "good" and "bad" revisions are known
- in order to identify a suspect commit.
-
-
-How To Use git-bisect To Isolate a Bogus Commit
-===============================================
-
-The way to use "git bisect" couldn't be easier.
-
-Figure out what the oldest bad state you know about is (that's usually the
-head of "master", since that's what you just tried to boot and failed at).
-Also, figure out the most recent known-good commit (usually the _previous_
-kernel you ran: and if you've only done a single "pull" in between, it
-will be ORIG_HEAD).
-
-Then do
-
- git bisect start
- git bisect bad master <- mark "master" as the bad state
- git bisect good ORIG_HEAD <- mark ORIG_HEAD as good (or
- whatever other known-good
- thing you booted last)
-
-and at this point "git bisect" will churn for a while, and tell you what
-the mid-point between those two commits are, and check that state out as
-the head of the new "bisect" branch.
-
-Compile and reboot.
-
-If it's good, just do
-
- git bisect good <- mark current head as good
-
-otherwise, reboot into a good kernel instead, and do (surprise surprise,
-git really is very intuitive):
-
- git bisect bad <- mark current head as bad
-
-and whatever you do, git will select a new half-way point. Do this for a
-while, until git tells you exactly which commit was the first bad commit.
-That's your culprit.
-
-It really works wonderfully well, except for the case where there was
-_another_ commit that broke something in between, like introduced some
-stupid compile error. In that case you should not mark that commit good or
-bad: you should try to find another commit close-by, and do a "git reset
---hard <newcommit>" to try out _that_ commit instead, and then test that
-instead (and mark it good or bad).
-
-You can do "git bisect visualize" while you do all this to see what's
-going on by starting up gitk on the bisection range.
-
-Finally, once you've figured out exactly which commit was bad, you can
-then go back to the master branch, and try reverting just that commit:
-
- git checkout master
- git revert <bad-commit-id>
-
-to verify that the top-of-kernel works with that single commit reverted.
-
diff --git a/Documentation/howto/maintain-git.txt b/Documentation/howto/maintain-git.txt
new file mode 100644
index 0000000000..4357e26913
--- /dev/null
+++ b/Documentation/howto/maintain-git.txt
@@ -0,0 +1,277 @@
+From: Junio C Hamano <gitster@pobox.com>
+Date: Wed, 21 Nov 2007 16:32:55 -0800
+Subject: Addendum to "MaintNotes"
+Abstract: Imagine that git development is racing along as usual, when our friendly
+ neighborhood maintainer is struck down by a wayward bus. Out of the
+ hordes of suckers (loyal developers), you have been tricked (chosen) to
+ step up as the new maintainer. This howto will show you "how to" do it.
+
+The maintainer's git time is spent on three activities.
+
+ - Communication (60%)
+
+ Mailing list discussions on general design, fielding user
+ questions, diagnosing bug reports; reviewing, commenting on,
+ suggesting alternatives to, and rejecting patches.
+
+ - Integration (30%)
+
+ Applying new patches from the contributors while spotting and
+ correcting minor mistakes, shuffling the integration and
+ testing branches, pushing the results out, cutting the
+ releases, and making announcements.
+
+ - Own development (10%)
+
+ Scratching my own itch and sending proposed patch series out.
+
+The policy on Integration is informally mentioned in "A Note
+from the maintainer" message, which is periodically posted to
+this mailing list after each feature release is made.
+
+The policy.
+
+ - Feature releases are numbered as vX.Y.Z and are meant to
+ contain bugfixes and enhancements in any area, including
+ functionality, performance and usability, without regression.
+
+ - Maintenance releases are numbered as vX.Y.Z.W and are meant
+ to contain only bugfixes for the corresponding vX.Y.Z feature
+ release and earlier maintenance releases vX.Y.Z.V (V < W).
+
+ - 'master' branch is used to prepare for the next feature
+ release. In other words, at some point, the tip of 'master'
+ branch is tagged with vX.Y.Z.
+
+ - 'maint' branch is used to prepare for the next maintenance
+ release. After the feature release vX.Y.Z is made, the tip
+ of 'maint' branch is set to that release, and bugfixes will
+ accumulate on the branch, and at some point, the tip of the
+ branch is tagged with vX.Y.Z.1, vX.Y.Z.2, and so on.
+
+ - 'next' branch is used to publish changes (both enhancements
+ and fixes) that (1) have worthwhile goal, (2) are in a fairly
+ good shape suitable for everyday use, (3) but have not yet
+ demonstrated to be regression free. New changes are tested
+ in 'next' before merged to 'master'.
+
+ - 'pu' branch is used to publish other proposed changes that do
+ not yet pass the criteria set for 'next'.
+
+ - The tips of 'master', 'maint' and 'next' branches will always
+ fast forward, to allow people to build their own
+ customization on top of them.
+
+ - Usually 'master' contains all of 'maint', 'next' contains all
+ of 'master' and 'pu' contains all of 'next'.
+
+ - The tip of 'master' is meant to be more stable than any
+ tagged releases, and the users are encouraged to follow it.
+
+ - The 'next' branch is where new action takes place, and the
+ users are encouraged to test it so that regressions and bugs
+ are found before new topics are merged to 'master'.
+
+
+A typical git day for the maintainer implements the above policy
+by doing the following:
+
+ - Scan mailing list and #git channel log. Respond with review
+ comments, suggestions etc. Kibitz. Collect potentially
+ usable patches from the mailing list. Patches about a single
+ topic go to one mailbox (I read my mail in Gnus, and type
+ \C-o to save/append messages in files in mbox format).
+
+ - Review the patches in the saved mailboxes. Edit proposed log
+ message for typofixes and clarifications, and add Acks
+ collected from the list. Edit patch to incorporate "Oops,
+ that should have been like this" fixes from the discussion.
+
+ - Classify the collected patches and handle 'master' and
+ 'maint' updates:
+
+ - Obviously correct fixes that pertain to the tip of 'maint'
+ are directly applied to 'maint'.
+
+ - Obviously correct fixes that pertain to the tip of 'master'
+ are directly applied to 'master'.
+
+ This step is done with "git am".
+
+ $ git checkout master ;# or "git checkout maint"
+ $ git am -3 -s mailbox
+ $ make test
+
+ - Merge downwards (maint->master):
+
+ $ git checkout master
+ $ git merge maint
+ $ make test
+
+ - Review the last issue of "What's cooking" message, review the
+ topics scheduled for merging upwards (topic->master and
+ topic->maint), and merge.
+
+ $ git checkout master ;# or "git checkout maint"
+ $ git merge ai/topic ;# or "git merge ai/maint-topic"
+ $ git log -p ORIG_HEAD.. ;# final review
+ $ git diff ORIG_HEAD.. ;# final review
+ $ make test ;# final review
+ $ git branch -d ai/topic ;# or "git branch -d ai/maint-topic"
+
+ - Merge downwards (maint->master) if needed:
+
+ $ git checkout master
+ $ git merge maint
+ $ make test
+
+ - Merge downwards (master->next) if needed:
+
+ $ git checkout next
+ $ git merge master
+ $ make test
+
+ - Handle the remaining patches:
+
+ - Anything unobvious that is applicable to 'master' (in other
+ words, does not depend on anything that is still in 'next'
+ and not in 'master') is applied to a new topic branch that
+ is forked from the tip of 'master'. This includes both
+ enhancements and unobvious fixes to 'master'. A topic
+ branch is named as ai/topic where "ai" is typically
+ author's initial and "topic" is a descriptive name of the
+ topic (in other words, "what's the series is about").
+
+ - An unobvious fix meant for 'maint' is applied to a new
+ topic branch that is forked from the tip of 'maint'. The
+ topic is named as ai/maint-topic.
+
+ - Changes that pertain to an existing topic are applied to
+ the branch, but:
+
+ - obviously correct ones are applied first;
+
+ - questionable ones are discarded or applied to near the tip;
+
+ - Replacement patches to an existing topic are accepted only
+ for commits not in 'next'.
+
+ The above except the "replacement" are all done with:
+
+ $ git am -3 -s mailbox
+
+ while patch replacement is often done by:
+
+ $ git format-patch ai/topic~$n..ai/topic ;# export existing
+
+ then replace some parts with the new patch, and reapplying:
+
+ $ git reset --hard ai/topic~$n
+ $ git am -3 -s 000*.txt
+
+ The full test suite is always run for 'maint' and 'master'
+ after patch application; for topic branches the tests are run
+ as time permits.
+
+ - Update "What's cooking" message to review the updates to
+ existing topics, newly added topics and graduated topics.
+
+ This step is helped with Meta/UWC script (where Meta/ contains
+ a checkout of the 'todo' branch).
+
+ - Merge topics to 'next'. For each branch whose tip is not
+ merged to 'next', one of three things can happen:
+
+ - The commits are all next-worthy; merge the topic to next:
+
+ $ git checkout next
+ $ git merge ai/topic ;# or "git merge ai/maint-topic"
+ $ make test
+
+ - The new parts are of mixed quality, but earlier ones are
+ next-worthy; merge the early parts to next:
+
+ $ git checkout next
+ $ git merge ai/topic~2 ;# the tip two are dubious
+ $ make test
+
+ - Nothing is next-worthy; do not do anything.
+
+ - Rebase topics that do not have any commit in next yet. This
+ step is optional but sometimes is worth doing when an old
+ series that is not in next can take advantage of low-level
+ framework change that is merged to 'master' already.
+
+ $ git rebase master ai/topic
+
+ This step is helped with Meta/git-topic.perl script to
+ identify which topic is rebaseable. There also is a
+ pre-rebase hook to make sure that topics that are already in
+ 'next' are not rebased beyond the merged commit.
+
+ - Rebuild "pu" to merge the tips of topics not in 'next'.
+
+ $ git checkout pu
+ $ git reset --hard next
+ $ git merge ai/topic ;# repeat for all remaining topics
+ $ make test
+
+ This step is helped with Meta/PU script
+
+ - Push four integration branches to a private repository at
+ k.org and run "make test" on all of them.
+
+ - Push four integration branches to /pub/scm/git/git.git at
+ k.org. This triggers its post-update hook which:
+
+ (1) runs "git pull" in $HOME/git-doc/ repository to pull
+ 'master' just pushed out;
+
+ (2) runs "make doc" in $HOME/git-doc/, install the generated
+ documentation in staging areas, which are separate
+ repositories that have html and man branches checked
+ out.
+
+ (3) runs "git commit" in the staging areas, and run "git
+ push" back to /pub/scm/git/git.git/ to update the html
+ and man branches.
+
+ (4) installs generated documentation to /pub/software/scm/git/docs/
+ to be viewed from http://www.kernel.org/
+
+ - Fetch html and man branches back from k.org, and push four
+ integration branches and the two documentation branches to
+ repo.or.cz
+
+
+Some observations to be made.
+
+ * Each topic is tested individually, and also together with
+ other topics cooking in 'next'. Until it matures, none part
+ of it is merged to 'master'.
+
+ * A topic already in 'next' can get fixes while still in
+ 'next'. Such a topic will have many merges to 'next' (in
+ other words, "git log --first-parent next" will show many
+ "Merge ai/topic to next" for the same topic.
+
+ * An unobvious fix for 'maint' is cooked in 'next' and then
+ merged to 'master' to make extra sure it is Ok and then
+ merged to 'maint'.
+
+ * Even when 'next' becomes empty (in other words, all topics
+ prove stable and are merged to 'master' and "git diff master
+ next" shows empty), it has tons of merge commits that will
+ never be in 'master'.
+
+ * In principle, "git log --first-parent master..next" should
+ show nothing but merges (in practice, there are fixup commits
+ and reverts that are not merges).
+
+ * Commits near the tip of a topic branch that are not in 'next'
+ are fair game to be discarded, replaced or rewritten.
+ Commits already merged to 'next' will not be.
+
+ * Being in the 'next' branch is not a guarantee for a topic to
+ be included in the next feature release. Being in the
+ 'master' branch typically is.
diff --git a/Documentation/howto/make-dist.txt b/Documentation/howto/make-dist.txt
deleted file mode 100644
index 00e330b293..0000000000
--- a/Documentation/howto/make-dist.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-Date: Fri, 12 Aug 2005 22:39:48 -0700 (PDT)
-From: Linus Torvalds <torvalds@osdl.org>
-To: Dave Jones <davej@redhat.com>
-cc: git@vger.kernel.org
-Subject: Re: Fwd: Re: git checkout -f branch doesn't remove extra files
-Abstract: In this article, Linus talks about building a tarball,
- incremental patch, and ChangeLog, given a base release and two
- rc releases, following the convention of giving the patch from
- the base release and the latest rc, with ChangeLog between the
- last rc and the latest rc.
-
-On Sat, 13 Aug 2005, Dave Jones wrote:
->
-> > Git actually has a _lot_ of nifty tools. I didn't realize that people
-> > didn't know about such basic stuff as "git-tar-tree" and "git-ls-files".
->
-> Maybe its because things are moving so fast :) Or maybe I just wasn't
-> paying attention on that day. (I even read the git changes via RSS,
-> so I should have no excuse).
-
-Well, git-tar-tree has been there since late April - it's actually one of
-those really early commands. I'm pretty sure the RSS feed came later ;)
-
-I use it all the time in doing releases, it's a lot faster than creating a
-tar tree by reading the filesystem (even if you don't have to check things
-out). A hidden pearl.
-
-This is my crappy "release-script":
-
- [torvalds@g5 ~]$ cat bin/release-script
- #!/bin/sh
- stable="$1"
- last="$2"
- new="$3"
- echo "# git-tag v$new"
- echo "git-tar-tree v$new linux-$new | gzip -9 > ../linux-$new.tar.gz"
- echo "git-diff-tree -p v$stable v$new | gzip -9 > ../patch-$new.gz"
- echo "git-rev-list --pretty v$new ^v$last > ../ChangeLog-$new"
- echo "git-rev-list --pretty=short v$new ^v$last | git-shortlog > ../ShortLog"
- echo "git-diff-tree -p v$last v$new | git-apply --stat > ../diffstat-$new"
-
-and when I want to do a new kernel release I literally first tag it, and
-then do
-
- release-script 2.6.12 2.6.13-rc6 2.6.13-rc7
-
-and check that things look sane, and then just cut-and-paste the commands.
-
-Yeah, it's stupid.
-
- Linus
-
diff --git a/Documentation/howto/rebase-and-edit.txt b/Documentation/howto/rebase-and-edit.txt
deleted file mode 100644
index 646c55cc69..0000000000
--- a/Documentation/howto/rebase-and-edit.txt
+++ /dev/null
@@ -1,81 +0,0 @@
-Date: Sat, 13 Aug 2005 22:16:02 -0700 (PDT)
-From: Linus Torvalds <torvalds@osdl.org>
-To: Steve French <smfrench@austin.rr.com>
-cc: git@vger.kernel.org
-Subject: Re: sending changesets from the middle of a git tree
-Abstract: In this article, Linus demonstrates how a broken commit
- in a sequence of commits can be removed by rewinding the head and
- reapplying selected changes.
-
-On Sat, 13 Aug 2005, Linus Torvalds wrote:
-
-> That's correct. Same things apply: you can move a patch over, and create a
-> new one with a modified comment, but basically the _old_ commit will be
-> immutable.
-
-Let me clarify.
-
-You can entirely _drop_ old branches, so commits may be immutable, but
-nothing forces you to keep them. Of course, when you drop a commit, you'll
-always end up dropping all the commits that depended on it, and if you
-actually got somebody else to pull that commit you can't drop it from
-_their_ repository, but undoing things is not impossible.
-
-For example, let's say that you've made a mess of things: you've committed
-three commits "old->a->b->c", and you notice that "a" was broken, but you
-want to save "b" and "c". What you can do is
-
- # Create a branch "broken" that is the current code
- # for reference
- git branch broken
-
- # Reset the main branch to three parents back: this
- # effectively undoes the three top commits
- git reset HEAD^^^
- git checkout -f
-
- # Check the result visually to make sure you know what's
- # going on
- gitk --all
-
- # Re-apply the two top ones from "broken"
- #
- # First "parent of broken" (aka b):
- git-diff-tree -p broken^ | git-apply --index
- git commit --reedit=broken^
-
- # Then "top of broken" (aka c):
- git-diff-tree -p broken | git-apply --index
- git commit --reedit=broken
-
-and you've now re-applied (and possibly edited the comments) the two
-commits b/c, and commit "a" is basically gone (it still exists in the
-"broken" branch, of course).
-
-Finally, check out the end result again:
-
- # Look at the new commit history
- gitk --all
-
-to see that everything looks sensible.
-
-And then, you can just remove the broken branch if you decide you really
-don't want it:
-
- # remove 'broken' branch
- git branch -d broken
-
- # Prune old objects if you're really really sure
- git prune
-
-And yeah, I'm sure there are other ways of doing this. And as usual, the
-above is totally untested, and I just wrote it down in this email, so if
-I've done something wrong, you'll have to figure it out on your own ;)
-
- Linus
--
-To unsubscribe from this list: send the line "unsubscribe git" in
-the body of a message to majordomo@vger.kernel.org
-More majordomo info at http://vger.kernel.org/majordomo-info.html
-
-
diff --git a/Documentation/howto/rebase-from-internal-branch.txt b/Documentation/howto/rebase-from-internal-branch.txt
index 3b3a5c2e69..74a1c0c4ba 100644
--- a/Documentation/howto/rebase-from-internal-branch.txt
+++ b/Documentation/howto/rebase-from-internal-branch.txt
@@ -1,4 +1,4 @@
-From: Junio C Hamano <junkio@cox.net>
+From: Junio C Hamano <gitster@pobox.com>
To: git@vger.kernel.org
Cc: Petr Baudis <pasky@suse.cz>, Linus Torvalds <torvalds@osdl.org>
Subject: Re: sending changesets from the middle of a git tree
@@ -14,10 +14,10 @@ Petr Baudis <pasky@suse.cz> writes:
> Dear diary, on Sun, Aug 14, 2005 at 09:57:13AM CEST, I got a letter
> where Junio C Hamano <junkio@cox.net> told me that...
>> Linus Torvalds <torvalds@osdl.org> writes:
->>
->> > Junio, maybe you want to talk about how you move patches from your "pu"
+>>
+>> > Junio, maybe you want to talk about how you move patches from your "pu"
>> > branch to the real branches.
->>
+>>
> Actually, wouldn't this be also precisely for what StGIT is intended to?
Exactly my feeling. I was sort of waiting for Catalin to speak
@@ -27,7 +27,7 @@ the kind of task StGIT is designed to do.
I just have done a simpler one, this time using only the core
GIT tools.
-I had a handful commits that were ahead of master in pu, and I
+I had a handful of commits that were ahead of master in pu, and I
wanted to add some documentation bypassing my usual habit of
placing new things in pu first. At the beginning, the commit
ancestry graph looked like this:
@@ -118,7 +118,7 @@ up your changes, along with other changes.
where *your "master" head
upstream --> #1 --> #2 --> #3
- used \
+ used \
to be \--> #A --> #2' --> #3' --> #B --> #C
*upstream head
@@ -133,7 +133,7 @@ You fetch from upstream, but not merge.
$ git fetch upstream
This leaves the updated upstream head in .git/FETCH_HEAD but
-does not touch your .git/HEAD nor .git/refs/heads/master.
+does not touch your .git/HEAD nor .git/refs/heads/master.
You run "git rebase" now.
$ git rebase FETCH_HEAD master
@@ -161,5 +161,3 @@ the #1' commit.
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
-
-
diff --git a/Documentation/howto/rebuild-from-update-hook.txt b/Documentation/howto/rebuild-from-update-hook.txt
index 02621b54a0..48c67568d3 100644
--- a/Documentation/howto/rebuild-from-update-hook.txt
+++ b/Documentation/howto/rebuild-from-update-hook.txt
@@ -1,6 +1,6 @@
Subject: [HOWTO] Using post-update hook
Message-ID: <7vy86o6usx.fsf@assigned-by-dhcp.cox.net>
-From: Junio C Hamano <junkio@cox.net>
+From: Junio C Hamano <gitster@pobox.com>
Date: Fri, 26 Aug 2005 18:19:10 -0700
Abstract: In this how-to article, JC talks about how he
uses the post-update hook to automate git documentation page
@@ -84,4 +84,3 @@ There are four things worth mentioning:
- This is still crude and does not protect against simultaneous
make invocations stomping on each other. I would need to add
some locking mechanism for this.
-
diff --git a/Documentation/howto/recover-corrupted-blob-object.txt b/Documentation/howto/recover-corrupted-blob-object.txt
new file mode 100644
index 0000000000..323b513ed0
--- /dev/null
+++ b/Documentation/howto/recover-corrupted-blob-object.txt
@@ -0,0 +1,134 @@
+Date: Fri, 9 Nov 2007 08:28:38 -0800 (PST)
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Subject: corrupt object on git-gc
+Abstract: Some tricks to reconstruct blob objects in order to fix
+ a corrupted repository.
+
+On Fri, 9 Nov 2007, Yossi Leybovich wrote:
+>
+> Did not help still the repository look for this object?
+> Any one know how can I track this object and understand which file is it
+
+So exactly *because* the SHA1 hash is cryptographically secure, the hash
+itself doesn't actually tell you anything, in order to fix a corrupt
+object you basically have to find the "original source" for it.
+
+The easiest way to do that is almost always to have backups, and find the
+same object somewhere else. Backups really are a good idea, and git makes
+it pretty easy (if nothing else, just clone the repository somewhere else,
+and make sure that you do *not* use a hard-linked clone, and preferably
+not the same disk/machine).
+
+But since you don't seem to have backups right now, the good news is that
+especially with a single blob being corrupt, these things *are* somewhat
+debuggable.
+
+First off, move the corrupt object away, and *save* it. The most common
+cause of corruption so far has been memory corruption, but even so, there
+are people who would be interested in seeing the corruption - but it's
+basically impossible to judge the corruption until we can also see the
+original object, so right now the corrupt object is useless, but it's very
+interesting for the future, in the hope that you can re-create a
+non-corrupt version.
+
+So:
+
+> ib]$ mv .git/objects/4b/9458b3786228369c63936db65827de3cc06200 ../
+
+This is the right thing to do, although it's usually best to save it under
+it's full SHA1 name (you just dropped the "4b" from the result ;).
+
+Let's see what that tells us:
+
+> ib]$ git-fsck --full
+> broken link from tree 2d9263c6d23595e7cb2a21e5ebbb53655278dff8
+> to blob 4b9458b3786228369c63936db65827de3cc06200
+> missing blob 4b9458b3786228369c63936db65827de3cc06200
+
+Ok, I removed the "dangling commit" messages, because they are just
+messages about the fact that you probably have rebased etc, so they're not
+at all interesting. But what remains is still very useful. In particular,
+we now know which tree points to it!
+
+Now you can do
+
+ git ls-tree 2d9263c6d23595e7cb2a21e5ebbb53655278dff8
+
+which will show something like
+
+ 100644 blob 8d14531846b95bfa3564b58ccfb7913a034323b8 .gitignore
+ 100644 blob ebf9bf84da0aab5ed944264a5db2a65fe3a3e883 .mailmap
+ 100644 blob ca442d313d86dc67e0a2e5d584b465bd382cbf5c COPYING
+ 100644 blob ee909f2cc49e54f0799a4739d24c4cb9151ae453 CREDITS
+ 040000 tree 0f5f709c17ad89e72bdbbef6ea221c69807009f6 Documentation
+ 100644 blob 1570d248ad9237e4fa6e4d079336b9da62d9ba32 Kbuild
+ 100644 blob 1c7c229a092665b11cd46a25dbd40feeb31661d9 MAINTAINERS
+ ...
+
+and you should now have a line that looks like
+
+ 10064 blob 4b9458b3786228369c63936db65827de3cc06200 my-magic-file
+
+in the output. This already tells you a *lot* it tells you what file the
+corrupt blob came from!
+
+Now, it doesn't tell you quite enough, though: it doesn't tell what
+*version* of the file didn't get correctly written! You might be really
+lucky, and it may be the version that you already have checked out in your
+working tree, in which case fixing this problem is really simple, just do
+
+ git hash-object -w my-magic-file
+
+again, and if it outputs the missing SHA1 (4b945..) you're now all done!
+
+But that's the really lucky case, so let's assume that it was some older
+version that was broken. How do you tell which version it was?
+
+The easiest way to do it is to do
+
+ git log --raw --all --full-history -- subdirectory/my-magic-file
+
+and that will show you the whole log for that file (please realize that
+the tree you had may not be the top-level tree, so you need to figure out
+which subdirectory it was in on your own), and because you're asking for
+raw output, you'll now get something like
+
+ commit abc
+ Author:
+ Date:
+ ..
+ :100644 100644 4b9458b... newsha... M somedirectory/my-magic-file
+
+
+ commit xyz
+ Author:
+ Date:
+
+ ..
+ :100644 100644 oldsha... 4b9458b... M somedirectory/my-magic-file
+
+and this actually tells you what the *previous* and *subsequent* versions
+of that file were! So now you can look at those ("oldsha" and "newsha"
+respectively), and hopefully you have done commits often, and can
+re-create the missing my-magic-file version by looking at those older and
+newer versions!
+
+If you can do that, you can now recreate the missing object with
+
+ git hash-object -w <recreated-file>
+
+and your repository is good again!
+
+(Btw, you could have ignored the fsck, and started with doing a
+
+ git log --raw --all
+
+and just looked for the sha of the missing object (4b9458b..) in that
+whole thing. It's up to you - git does *have* a lot of information, it is
+just missing one particular blob version.
+
+Trying to recreate trees and especially commits is *much* harder. So you
+were lucky that it's a blob. It's quite possible that you can recreate the
+thing.
+
+ Linus
diff --git a/Documentation/howto/revert-a-faulty-merge.txt b/Documentation/howto/revert-a-faulty-merge.txt
new file mode 100644
index 0000000000..3b4a390005
--- /dev/null
+++ b/Documentation/howto/revert-a-faulty-merge.txt
@@ -0,0 +1,179 @@
+Date: Fri, 19 Dec 2008 00:45:19 -0800
+From: Linus Torvalds <torvalds@linux-foundation.org>, Junio C Hamano <gitster@pobox.com>
+Subject: Re: Odd merge behaviour involving reverts
+Abstract: Sometimes a branch that was already merged to the mainline
+ is later found to be faulty. Linus and Junio give guidance on
+ recovering from such a premature merge and continuing development
+ after the offending branch is fixed.
+Message-ID: <7vocz8a6zk.fsf@gitster.siamese.dyndns.org>
+References: <alpine.LFD.2.00.0812181949450.14014@localhost.localdomain>
+
+Alan <alan@clueserver.org> said:
+
+ I have a master branch. We have a branch off of that that some
+ developers are doing work on. They claim it is ready. We merge it
+ into the master branch. It breaks something so we revert the merge.
+ They make changes to the code. they get it to a point where they say
+ it is ok and we merge again.
+
+ When examined, we find that code changes made before the revert are
+ not in the master branch, but code changes after are in the master
+ branch.
+
+and asked for help recovering from this situation.
+
+The history immediately after the "revert of the merge" would look like
+this:
+
+ ---o---o---o---M---x---x---W
+ /
+ ---A---B
+
+where A and B are on the side development that was not so good, M is the
+merge that brings these premature changes into the mainline, x are changes
+unrelated to what the side branch did and already made on the mainline,
+and W is the "revert of the merge M" (doesn't W look M upside down?).
+IOW, "diff W^..W" is similar to "diff -R M^..M".
+
+Such a "revert" of a merge can be made with:
+
+ $ git revert -m 1 M
+
+After the developers of the side branch fix their mistakes, the history
+may look like this:
+
+ ---o---o---o---M---x---x---W---x
+ /
+ ---A---B-------------------C---D
+
+where C and D are to fix what was broken in A and B, and you may already
+have some other changes on the mainline after W.
+
+If you merge the updated side branch (with D at its tip), none of the
+changes made in A nor B will be in the result, because they were reverted
+by W. That is what Alan saw.
+
+Linus explains the situation:
+
+ Reverting a regular commit just effectively undoes what that commit
+ did, and is fairly straightforward. But reverting a merge commit also
+ undoes the _data_ that the commit changed, but it does absolutely
+ nothing to the effects on _history_ that the merge had.
+
+ So the merge will still exist, and it will still be seen as joining
+ the two branches together, and future merges will see that merge as
+ the last shared state - and the revert that reverted the merge brought
+ in will not affect that at all.
+
+ So a "revert" undoes the data changes, but it's very much _not_ an
+ "undo" in the sense that it doesn't undo the effects of a commit on
+ the repository history.
+
+ So if you think of "revert" as "undo", then you're going to always
+ miss this part of reverts. Yes, it undoes the data, but no, it doesn't
+ undo history.
+
+In such a situation, you would want to first revert the previous revert,
+which would make the history look like this:
+
+ ---o---o---o---M---x---x---W---x---Y
+ /
+ ---A---B-------------------C---D
+
+where Y is the revert of W. Such a "revert of the revert" can be done
+with:
+
+ $ git revert W
+
+This history would (ignoring possible conflicts between what W and W..Y
+changed) be equivalent to not having W nor Y at all in the history:
+
+ ---o---o---o---M---x---x-------x----
+ /
+ ---A---B-------------------C---D
+
+and merging the side branch again will not have conflict arising from an
+earlier revert and revert of the revert.
+
+ ---o---o---o---M---x---x-------x-------*
+ / /
+ ---A---B-------------------C---D
+
+Of course the changes made in C and D still can conflict with what was
+done by any of the x, but that is just a normal merge conflict.
+
+On the other hand, if the developers of the side branch discarded their
+faulty A and B, and redone the changes on top of the updated mainline
+after the revert, the history would have looked like this:
+
+ ---o---o---o---M---x---x---W---x---x
+ / \
+ ---A---B A'--B'--C'
+
+If you reverted the revert in such a case as in the previous example:
+
+ ---o---o---o---M---x---x---W---x---x---Y---*
+ / \ /
+ ---A---B A'--B'--C'
+
+where Y is the revert of W, A' and B' are rerolled A and B, and there may
+also be a further fix-up C' on the side branch. "diff Y^..Y" is similar
+to "diff -R W^..W" (which in turn means it is similar to "diff M^..M"),
+and "diff A'^..C'" by definition would be similar but different from that,
+because it is a rerolled series of the earlier change. There will be a
+lot of overlapping changes that result in conflicts. So do not do "revert
+of revert" blindly without thinking..
+
+ ---o---o---o---M---x---x---W---x---x
+ / \
+ ---A---B A'--B'--C'
+
+In the history with rebased side branch, W (and M) are behind the merge
+base of the updated branch and the tip of the mainline, and they should
+merge without the past faulty merge and its revert getting in the way.
+
+To recap, these are two very different scenarios, and they want two very
+different resolution strategies:
+
+ - If the faulty side branch was fixed by adding corrections on top, then
+ doing a revert of the previous revert would be the right thing to do.
+
+ - If the faulty side branch whose effects were discarded by an earlier
+ revert of a merge was rebuilt from scratch (i.e. rebasing and fixing,
+ as you seem to have interpreted), then re-merging the result without
+ doing anything else fancy would be the right thing to do.
+
+However, there are things to keep in mind when reverting a merge (and
+reverting such a revert).
+
+For example, think about what reverting a merge (and then reverting the
+revert) does to bisectability. Ignore the fact that the revert of a revert
+is undoing it - just think of it as a "single commit that does a lot".
+Because that is what it does.
+
+When you have a problem you are chasing down, and you hit a "revert this
+merge", what you're hitting is essentially a single commit that contains
+all the changes (but obviously in reverse) of all the commits that got
+merged. So it's debugging hell, because now you don't have lots of small
+changes that you can try to pinpoint which _part_ of it changes.
+
+But does it all work? Sure it does. You can revert a merge, and from a
+purely technical angle, git did it very naturally and had no real
+troubles. It just considered it a change from "state before merge" to
+"state after merge", and that was it. Nothing complicated, nothing odd,
+nothing really dangerous. Git will do it without even thinking about it.
+
+So from a technical angle, there's nothing wrong with reverting a merge,
+but from a workflow angle it's something that you generally should try to
+avoid.
+
+If at all possible, for example, if you find a problem that got merged
+into the main tree, rather than revert the merge, try _really_ hard to
+bisect the problem down into the branch you merged, and just fix it, or
+try to revert the individual commit that caused it.
+
+Yes, it's more complex, and no, it's not always going to work (sometimes
+the answer is: "oops, I really shouldn't have merged it, because it wasn't
+ready yet, and I really need to undo _all_ of the merge"). So then you
+really should revert the merge, but when you want to re-do the merge, you
+now need to do it by reverting the revert.
diff --git a/Documentation/howto/revert-branch-rebase.txt b/Documentation/howto/revert-branch-rebase.txt
index d88ec23a97..e70d8a31e7 100644
--- a/Documentation/howto/revert-branch-rebase.txt
+++ b/Documentation/howto/revert-branch-rebase.txt
@@ -1,4 +1,4 @@
-From: Junio C Hamano <junkio@cox.net>
+From: Junio C Hamano <gitster@pobox.com>
To: git@vger.kernel.org
Subject: [HOWTO] Reverting an existing commit
Abstract: In this article, JC gives a small real-life example of using
@@ -146,7 +146,7 @@ Everything is in the good order. I do not need the temporary branch
nor tag anymore, so remove them:
------------------------------------------------
-$ rm -f .git/refs/tags/pu-anchor
+$ rm -f .git/refs/tags/pu-anchor
$ git branch -d revert-c99
------------------------------------------------
diff --git a/Documentation/howto/separating-topic-branches.txt b/Documentation/howto/separating-topic-branches.txt
index 090e2c9b01..6d3eb8ed00 100644
--- a/Documentation/howto/separating-topic-branches.txt
+++ b/Documentation/howto/separating-topic-branches.txt
@@ -1,4 +1,4 @@
-From: Junio C Hamano <junkio@cox.net>
+From: Junio C Hamano <gitster@pobox.com>
Subject: Separating topic branches
Abstract: In this article, JC describes how to separate topic branches.
@@ -12,7 +12,7 @@ up with a history like this:
"master"
o---o
- \ "topic"
+ \ "topic"
o---o---o---o---o---o
At this point, "topic" contains something I know I want, but it
@@ -29,11 +29,11 @@ start building on top of "master":
$ git checkout -b topicA master
... pick and apply pieces from P.diff to build
... commits on topicA branch.
-
+
o---o---o
/ "topicA"
o---o"master"
- \ "topic"
+ \ "topic"
o---o---o---o---o---o
Before doing each commit on "topicA" HEAD, I run "diff HEAD"
@@ -59,7 +59,7 @@ other topic:
/o---o---o
|/ "topicA"
o---o"master"
- \ "topic"
+ \ "topic"
o---o---o---o---o---o
After I am done, I'd try a pretend-merge between "topicA" and
@@ -73,7 +73,7 @@ After I am done, I'd try a pretend-merge between "topicA" and
/o---o---o----------'
|/ "topicA"
o---o"master"
- \ "topic"
+ \ "topic"
o---o---o---o---o---o
The last diff better not to show anything other than cleanups
@@ -84,8 +84,7 @@ for crufts. Then I can finally clean things up:
"topicB"
o---o---o---o---o
- /
+ /
/o---o---o
|/ "topicA"
o---o"master"
-
diff --git a/Documentation/howto/setup-git-server-over-http.txt b/Documentation/howto/setup-git-server-over-http.txt
index 8eadc20494..622ee5c8dd 100644
--- a/Documentation/howto/setup-git-server-over-http.txt
+++ b/Documentation/howto/setup-git-server-over-http.txt
@@ -1,5 +1,5 @@
From: Rutger Nijlunsing <rutger@nospam.com>
-Subject: Setting up a git repository which can be pushed into and pulled from over HTTP.
+Subject: Setting up a git repository which can be pushed into and pulled from over HTTP(S).
Date: Thu, 10 Aug 2006 22:00:26 +0200
Since Apache is one of those packages people like to compile
@@ -40,9 +40,13 @@ What's needed:
- have permissions to chown a directory
-- have git installed at the server _and_ client
+- have git installed on the client, and
-In effect, this probably means you're going to be root.
+- either have git installed on the server or have a webdav client on
+ the client.
+
+In effect, this means you're going to be root, or that you're using a
+preconfigured WebDAV server.
Step 1: setup a bare GIT repository
@@ -50,9 +54,9 @@ Step 1: setup a bare GIT repository
At the time of writing, git-http-push cannot remotely create a GIT
repository. So we have to do that at the server side with git. Another
-option would be to generate an empty repository at the client and copy
-it to the server with WebDAV. But then you're probably the first to
-try that out :)
+option is to generate an empty bare repository at the client and copy
+it to the server with a WebDAV client (which is the only option if Git
+is not installed on the server).
Create the directory under the DocumentRoot of the directories served
by Apache. As an example we take /usr/local/apache2, but try "grep
@@ -139,7 +143,7 @@ Then, add something like this to your httpd.conf
Require valid-user
</Location>
- Debian automatically reads all files under /etc/apach2/conf.d.
+ Debian automatically reads all files under /etc/apache2/conf.d.
The password file can be somewhere else, but it has to be readable by
Apache and preferably not readable by the world.
@@ -169,7 +173,9 @@ On Debian:
Most tests should pass.
-A command line tool to test WebDAV is cadaver.
+A command line tool to test WebDAV is cadaver. If you prefer GUIs, for
+example, konqueror can open WebDAV URLs as "webdav://..." or
+"webdavs://...".
If you're into Windows, from XP onwards Internet Explorer supports
WebDAV. For this, do Internet Explorer -> Open Location ->
@@ -179,8 +185,9 @@ http://<servername>/my-new-repo.git [x] Open as webfolder -> login .
Step 3: setup the client
------------------------
-Make sure that you have HTTP support, i.e. your git was built with curl.
-The easiest way to check is to look for the executable 'git-http-push'.
+Make sure that you have HTTP support, i.e. your git was built with
+libcurl (version more recent than 7.10). The command 'git http-push' with
+no argument should display a usage message.
Then, add the following to your $HOME/.netrc (you can do without, but will be
asked to input your password a _lot_ of times):
@@ -197,10 +204,10 @@ instead of the server name.
To check whether all is OK, do:
- curl --netrc --location -v http://<username>@<servername>/my-new-repo.git/
-
-...this should give a directory listing in HTML of /var/www/my-new-repo.git .
+ curl --netrc --location -v http://<username>@<servername>/my-new-repo.git/HEAD
+...this should give something like 'ref: refs/heads/master', which is
+the content of the file HEAD on the server.
Now, add the remote in your existing repository which contains the project
you want to export:
@@ -225,6 +232,15 @@ want to export) to repository called 'upload', which we previously
defined with git-config.
+Using a proxy:
+--------------
+
+If you have to access the WebDAV server from behind an HTTP(S) proxy,
+set the variable 'all_proxy' to 'http://proxy-host.com:port', or
+'http://login-on-proxy:passwd-on-proxy@proxy-host.com:port'. See 'man
+curl' for details.
+
+
Troubleshooting:
----------------
@@ -248,9 +264,14 @@ Reading /usr/local/apache2/logs/error_log is often helpful.
On Debian: Read /var/log/apache2/error.log instead.
+If you access HTTPS locations, git may fail verifying the SSL
+certificate (this is return code 60). Setting http.sslVerify=false can
+help diagnosing the problem, but removes security checks.
+
Debian References: http://www.debian-administration.org/articles/285
Authors
Johannes Schindelin <Johannes.Schindelin@gmx.de>
Rutger Nijlunsing <git@wingding.demon.nl>
+ Matthieu Moy <Matthieu.Moy@imag.fr>
diff --git a/Documentation/howto/update-hook-example.txt b/Documentation/howto/update-hook-example.txt
index 3a33696f00..697d918885 100644
--- a/Documentation/howto/update-hook-example.txt
+++ b/Documentation/howto/update-hook-example.txt
@@ -1,4 +1,4 @@
-From: Junio C Hamano <junkio@cox.net> and Carl Baldwin <cnb@fc.hp.com>
+From: Junio C Hamano <gitster@pobox.com> and Carl Baldwin <cnb@fc.hp.com>
Subject: control access to branches.
Date: Thu, 17 Nov 2005 23:55:32 -0800
Message-ID: <7vfypumlu3.fsf@assigned-by-dhcp.cox.net>
@@ -65,10 +65,10 @@ function info {
# Implement generic branch and tag policies.
# - Tags should not be updated once created.
-# - Branches should only be fast-forwarded.
+# - Branches should only be fast-forwarded unless their pattern starts with '+'
case "$1" in
refs/tags/*)
- [ -f "$GIT_DIR/$1" ] &&
+ git rev-parse --verify -q "$1" &&
deny >/dev/null "You can't overwrite an existing tag"
;;
refs/heads/*)
@@ -80,7 +80,7 @@ case "$1" in
mb=$(git-merge-base "$2" "$3")
case "$mb,$2" in
"$2,$mb") info "Update is fast-forward" ;;
- *) deny >/dev/null "This is not a fast-forward update." ;;
+ *) noff=y; info "This is not a fast-forward update.";;
esac
fi
;;
@@ -95,21 +95,30 @@ allowed_users_file=$GIT_DIR/info/allowed-users
username=$(id -u -n)
info "The user is: '$username'"
-if [ -f "$allowed_users_file" ]; then
+if test -f "$allowed_users_file"
+then
rc=$(cat $allowed_users_file | grep -v '^#' | grep -v '^$' |
- while read head_pattern user_patterns; do
- matchlen=$(expr "$1" : "$head_pattern")
- if [ "$matchlen" == "${#1}" ]; then
- info "Found matching head pattern: '$head_pattern'"
- for user_pattern in $user_patterns; do
- info "Checking user: '$username' against pattern: '$user_pattern'"
- matchlen=$(expr "$username" : "$user_pattern")
- if [ "$matchlen" == "${#username}" ]; then
- grant "Allowing user: '$username' with pattern: '$user_pattern'"
- fi
- done
- deny "The user is not in the access list for this branch"
- fi
+ while read heads user_patterns
+ do
+ # does this rule apply to us?
+ head_pattern=${heads#+}
+ matchlen=$(expr "$1" : "${head_pattern#+}")
+ test "$matchlen" = ${#1} || continue
+
+ # if non-ff, $heads must be with the '+' prefix
+ test -n "$noff" &&
+ test "$head_pattern" = "$heads" && continue
+
+ info "Found matching head pattern: '$head_pattern'"
+ for user_pattern in $user_patterns; do
+ info "Checking user: '$username' against pattern: '$user_pattern'"
+ matchlen=$(expr "$username" : "$user_pattern")
+ if test "$matchlen" = "${#username}"
+ then
+ grant "Allowing user: '$username' with pattern: '$user_pattern'"
+ fi
+ done
+ deny "The user is not in the access list for this branch"
done
)
case "$rc" in
@@ -124,23 +133,32 @@ groups=$(id -G -n)
info "The user belongs to the following groups:"
info "'$groups'"
-if [ -f "$allowed_groups_file" ]; then
+if test -f "$allowed_groups_file"
+then
rc=$(cat $allowed_groups_file | grep -v '^#' | grep -v '^$' |
- while read head_pattern group_patterns; do
- matchlen=$(expr "$1" : "$head_pattern")
- if [ "$matchlen" == "${#1}" ]; then
- info "Found matching head pattern: '$head_pattern'"
- for group_pattern in $group_patterns; do
- for groupname in $groups; do
- info "Checking group: '$groupname' against pattern: '$group_pattern'"
- matchlen=$(expr "$groupname" : "$group_pattern")
- if [ "$matchlen" == "${#groupname}" ]; then
- grant "Allowing group: '$groupname' with pattern: '$group_pattern'"
- fi
- done
+ while read heads group_patterns
+ do
+ # does this rule apply to us?
+ head_pattern=${heads#+}
+ matchlen=$(expr "$1" : "${head_pattern#+}")
+ test "$matchlen" = ${#1} || continue
+
+ # if non-ff, $heads must be with the '+' prefix
+ test -n "$noff" &&
+ test "$head_pattern" = "$heads" && continue
+
+ info "Found matching head pattern: '$head_pattern'"
+ for group_pattern in $group_patterns; do
+ for groupname in $groups; do
+ info "Checking group: '$groupname' against pattern: '$group_pattern'"
+ matchlen=$(expr "$groupname" : "$group_pattern")
+ if test "$matchlen" = "${#groupname}"
+ then
+ grant "Allowing group: '$groupname' with pattern: '$group_pattern'"
+ fi
done
- deny "None of the user's groups are in the access list for this branch"
- fi
+ done
+ deny "None of the user's groups are in the access list for this branch"
done
)
case "$rc" in
@@ -158,15 +176,17 @@ This uses two files, $GIT_DIR/info/allowed-users and
allowed-groups, to describe which heads can be pushed into by
whom. The format of each file would look like this:
- refs/heads/master junio
+ refs/heads/master junio
+ +refs/heads/pu junio
refs/heads/cogito$ pasky
- refs/heads/bw/ linus
- refs/heads/tmp/ *
- refs/tags/v[0-9]* junio
+ refs/heads/bw/.* linus
+ refs/heads/tmp/.* .*
+ refs/tags/v[0-9].* junio
With this, Linus can push or create "bw/penguin" or "bw/zebra"
or "bw/panda" branches, Pasky can do only "cogito", and JC can
-do master branch and make versioned tags. And anybody can do
-tmp/blah branches.
+do master and pu branches and make versioned tags. And anybody
+can do tmp/blah branches. The '+' sign at the pu record means
+that JC can make non-fast-forward pushes on it.
------------
diff --git a/Documentation/howto/use-git-daemon.txt b/Documentation/howto/use-git-daemon.txt
index 1a1eb246bf..4e2f75cb61 100644
--- a/Documentation/howto/use-git-daemon.txt
+++ b/Documentation/howto/use-git-daemon.txt
@@ -49,4 +49,3 @@ Now, test your daemon with
$ git ls-remote git://127.0.0.1/rule-the-world.git
If this does not work, find out why, and submit a patch to this document.
-
diff --git a/Documentation/howto/using-merge-subtree.txt b/Documentation/howto/using-merge-subtree.txt
new file mode 100644
index 0000000000..0953a50b69
--- /dev/null
+++ b/Documentation/howto/using-merge-subtree.txt
@@ -0,0 +1,75 @@
+Date: Sat, 5 Jan 2008 20:17:40 -0500
+From: Sean <seanlkml@sympatico.ca>
+To: Miklos Vajna <vmiklos@frugalware.org>
+Cc: git@vger.kernel.org
+Subject: how to use git merge -s subtree?
+Abstract: In this article, Sean demonstrates how one can use the subtree merge
+ strategy.
+Content-type: text/asciidoc
+Message-ID: <BAYC1-PASMTP12374B54BA370A1E1C6E78AE4E0@CEZ.ICE>
+
+How to use the subtree merge strategy
+=====================================
+
+There are situations where you want to include contents in your project
+from an independently developed project. You can just pull from the
+other project as long as there are no conflicting paths.
+
+The problematic case is when there are conflicting files. Potential
+candidates are Makefiles and other standard filenames. You could merge
+these files but probably you do not want to. A better solution for this
+problem can be to merge the project as its own subdirectory. This is not
+supported by the 'recursive' merge strategy, so just pulling won't work.
+
+What you want is the 'subtree' merge strategy, which helps you in such a
+situation.
+
+In this example, let's say you have the repository at `/path/to/B` (but
+it can be an URL as well, if you want). You want to merge the 'master'
+branch of that repository to the `dir-B` subdirectory in your current
+branch.
+
+Here is the command sequence you need:
+
+----------------
+$ git remote add -f Bproject /path/to/B <1>
+$ git merge -s ours --no-commit Bproject/master <2>
+$ git read-tree --prefix=dir-B/ -u Bproject/master <3>
+$ git commit -m "Merge B project as our subdirectory" <4>
+
+$ git pull -s subtree Bproject master <5>
+----------------
+<1> name the other project "Bproject", and fetch.
+<2> prepare for the later step to record the result as a merge.
+<3> read "master" branch of Bproject to the subdirectory "dir-B".
+<4> record the merge result.
+<5> maintain the result with subsequent merges using "subtree"
+
+The first four commands are used for the initial merge, while the last
+one is to merge updates from 'B project'.
+
+Comparing 'subtree' merge with submodules
+-----------------------------------------
+
+- The benefit of using subtree merge is that it requires less
+ administrative burden from the users of your repository. It works with
+ older (before Git v1.5.2) clients and you have the code right after
+ clone.
+
+- However if you use submodules then you can choose not to transfer the
+ submodule objects. This may be a problem with the subtree merge.
+
+- Also, in case you make changes to the other project, it is easier to
+ submit changes if you just use submodules.
+
+Additional tips
+---------------
+
+- If you made changes to the other project in your repository, they may
+ want to merge from your project. This is possible using subtree -- it
+ can shift up the paths in your tree and then they can merge only the
+ relevant parts of your tree.
+
+- Please note that if the other project merges from you, then it will
+ connects its history to yours, which can be something they don't want
+ to.
diff --git a/Documentation/howto/using-topic-branches.txt b/Documentation/howto/using-topic-branches.txt
deleted file mode 100644
index 2c98194cb8..0000000000
--- a/Documentation/howto/using-topic-branches.txt
+++ /dev/null
@@ -1,296 +0,0 @@
-Date: Mon, 15 Aug 2005 12:17:41 -0700
-From: tony.luck@intel.com
-Subject: Some tutorial text (was git/cogito workshop/bof at linuxconf au?)
-Abstract: In this article, Tony Luck discusses how he uses GIT
- as a Linux subsystem maintainer.
-
-Here's something that I've been putting together on how I'm using
-GIT as a Linux subsystem maintainer.
-
--Tony
-
-Last updated w.r.t. GIT 1.1
-
-Linux subsystem maintenance using GIT
--------------------------------------
-
-My requirements here are to be able to create two public trees:
-
-1) A "test" tree into which patches are initially placed so that they
-can get some exposure when integrated with other ongoing development.
-This tree is available to Andrew for pulling into -mm whenever he wants.
-
-2) A "release" tree into which tested patches are moved for final
-sanity checking, and as a vehicle to send them upstream to Linus
-(by sending him a "please pull" request.)
-
-Note that the period of time that each patch spends in the "test" tree
-is dependent on the complexity of the change. Since GIT does not support
-cherry picking, it is not practical to simply apply all patches to the
-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 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
-that I could so this far more efficiently using branches inside a single
-GIT repository.
-
-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 git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git work
-
-Change directory into the cloned tree you just created
-
- $ cd work
-
-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: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
- Pull: master:linus
- ^D
-
-and create the linus branch:
-
- $ git branch linus
-
-The "linus" branch will be used to track the upstream kernel. To update it,
-you simply run:
-
- $ git fetch linus
-
-you can do this frequently (and it should be safe to do so with pending
-work in your tree, but perhaps not if you are in mid-merge).
-
-If you need to keep track of other public trees, you can add remote branches
-for them too:
-
- $ git branch another
- $ cat > .git/remotes/another
- URL: ... insert URL here ...
- Pull: name-of-branch-in-this-remote-tree:another
- ^D
-
-and run:
-
- $ git fetch another
-
-Now create the branches in which you are going to work, these start
-out at the current tip of the linus branch.
-
- $ git branch test linus
- $ git branch release linus
-
-These can be easily kept up to date by merging from the "linus" branch:
-
- $ git checkout test && git merge "Auto-update from upstream" test linus
- $ git checkout release && git merge "Auto-update from upstream" release linus
-
-Important note! If you have any local changes in these branches, then
-this merge will create a commit object in the history (with no local
-changes git will simply do a "Fast forward" merge). Many people dislike
-the "noise" that this creates in the Linux history, so you should avoid
-doing this capriciously in the "release" branch, as these noisy commits
-will become part of the permanent history when you ask Linus to pull
-from the release branch.
-
-Set up so that you can push upstream to your public tree (you need to
-log-in to the remote system and create an empty tree there before the
-first push).
-
- $ cat > .git/remotes/mytree
- URL: master.kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6.git
- Push: release
- Push: test
- ^D
-
-and the push both the test and release trees using:
-
- $ git push mytree
-
-or push just one of the test and release branches using:
-
- $ git push mytree test
-or
- $ git push mytree release
-
-Now to apply some patches from the community. Think of a short
-snappy name for a branch to hold this patch (or related group of
-patches), and create a new branch from the current tip of the
-linus branch:
-
- $ git checkout -b speed-up-spinlocks linus
-
-Now you apply the patch(es), run some tests, and commit the change(s). If
-the patch is a multi-part series, then you should apply each as a separate
-commit to this branch.
-
- $ ... patch ... test ... commit [ ... patch ... test ... commit ]*
-
-When you are happy with the state of this change, you can pull it into the
-"test" branch in preparation to make it public:
-
- $ git checkout test && git merge "Pull speed-up-spinlock changes" test speed-up-spinlocks
-
-It is unlikely that you would have any conflicts here ... but you might if you
-spent a while on this step and had also pulled new versions from upstream.
-
-Some time later when enough time has passed and testing done, you can pull the
-same branch into the "release" tree ready to go upstream. This is where you
-see the value of keeping each patch (or patch series) in its own branch. It
-means that the patches can be moved into the "release" tree in any order.
-
- $ git checkout release && git merge "Pull speed-up-spinlock changes" release speed-up-spinlocks
-
-After a while, you will have a number of branches, and despite the
-well chosen names you picked for each of them, you may forget what
-they are for, or what status they are in. To get a reminder of what
-changes are in a specific branch, use:
-
- $ git-whatchanged branchname ^linus | git-shortlog
-
-To see whether it has already been merged into the test or release branches
-use:
-
- $ git-rev-list branchname ^test
-or
- $ git-rev-list branchname ^release
-
-[If this branch has not yet been merged you will see a set of SHA1 values
-for the commits, if it has been merged, then there will be no output]
-
-Once a patch completes the great cycle (moving from test to release, then
-pulled by Linus, and finally coming back into your local "linus" branch)
-the branch for this change is no longer needed. You detect this when the
-output from:
-
- $ git-rev-list branchname ^linus
-
-is empty. At this point the branch can be deleted:
-
- $ git branch -d branchname
-
-Some changes are so trivial that it is not necessary to create a separate
-branch and then merge into each of the test and release branches. For
-these changes, just apply directly to the "release" branch, and then
-merge that into the "test" branch.
-
-To create diffstat and shortlog summaries of changes to include in a "please
-pull" request to Linus you can use:
-
- $ git-whatchanged -p release ^linus | diffstat -p1
-and
- $ git-whatchanged release ^linus | git-shortlog
-
-
-Here are some of the scripts that I use to simplify all this even further.
-
-==== update script ====
-# Update a branch in my GIT tree. If the branch to be updated
-# is "linus", then pull from kernel.org. Otherwise merge local
-# linus branch into test|release branch
-
-case "$1" in
-test|release)
- git checkout $1 && git merge "Auto-update from upstream" $1 linus
- ;;
-linus)
- before=$(cat .git/refs/heads/linus)
- git fetch linus
- after=$(cat .git/refs/heads/linus)
- if [ $before != $after ]
- then
- git-whatchanged $after ^$before | git-shortlog
- fi
- ;;
-*)
- echo "Usage: $0 linus|test|release" 1>&2
- exit 1
- ;;
-esac
-
-==== merge script ====
-# Merge a branch into either the test or release branch
-
-pname=$0
-
-usage()
-{
- echo "Usage: $pname branch test|release" 1>&2
- exit 1
-}
-
-if [ ! -f .git/refs/heads/"$1" ]
-then
- echo "Can't see branch <$1>" 1>&2
- usage
-fi
-
-case "$2" in
-test|release)
- if [ $(git-rev-list $1 ^$2 | wc -c) -eq 0 ]
- then
- echo $1 already merged into $2 1>&2
- exit 1
- fi
- git checkout $2 && git merge "Pull $1 into $2 branch" $2 $1
- ;;
-*)
- usage
- ;;
-esac
-
-==== status script ====
-# report on status of my ia64 GIT tree
-
-gb=$(tput setab 2)
-rb=$(tput setab 1)
-restore=$(tput setab 9)
-
-if [ `git-rev-list release ^test | wc -c` -gt 0 ]
-then
- echo $rb Warning: commits in release that are not in test $restore
- git-whatchanged release ^test
-fi
-
-for branch in `ls .git/refs/heads`
-do
- if [ $branch = linus -o $branch = test -o $branch = release ]
- then
- continue
- fi
-
- echo -n $gb ======= $branch ====== $restore " "
- status=
- for ref in test release linus
- do
- if [ `git-rev-list $branch ^$ref | wc -c` -gt 0 ]
- then
- status=$status${ref:0:1}
- fi
- done
- case $status in
- trl)
- echo $rb Need to pull into test $restore
- ;;
- rl)
- echo "In test"
- ;;
- l)
- echo "Waiting for linus"
- ;;
- "")
- echo $rb All done $restore
- ;;
- *)
- echo $rb "<$status>" $restore
- ;;
- esac
- git-whatchanged $branch ^linus | git-shortlog
-done