diff options
Diffstat (limited to 'Documentation/howto')
-rw-r--r-- | Documentation/howto/maintain-git.txt | 277 | ||||
-rw-r--r-- | Documentation/howto/rebase-and-edit.txt | 79 | ||||
-rw-r--r-- | Documentation/howto/rebase-from-internal-branch.txt | 4 | ||||
-rw-r--r-- | Documentation/howto/rebuild-from-update-hook.txt | 2 | ||||
-rw-r--r-- | Documentation/howto/recover-corrupted-blob-object.txt | 134 | ||||
-rw-r--r-- | Documentation/howto/revert-a-faulty-merge.txt | 179 | ||||
-rw-r--r-- | Documentation/howto/revert-branch-rebase.txt | 6 | ||||
-rw-r--r-- | Documentation/howto/separating-topic-branches.txt | 2 | ||||
-rw-r--r-- | Documentation/howto/setup-git-server-over-http.txt | 47 | ||||
-rw-r--r-- | Documentation/howto/update-hook-example.txt | 100 | ||||
-rw-r--r-- | Documentation/howto/using-merge-subtree.txt | 75 |
11 files changed, 766 insertions, 139 deletions
diff --git a/Documentation/howto/maintain-git.txt b/Documentation/howto/maintain-git.txt new file mode 100644 index 0000000000..d527b30770 --- /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/rebase-and-edit.txt b/Documentation/howto/rebase-and-edit.txt deleted file mode 100644 index 554909fe08..0000000000 --- a/Documentation/howto/rebase-and-edit.txt +++ /dev/null @@ -1,79 +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 7a76045eb7..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 @@ -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: diff --git a/Documentation/howto/rebuild-from-update-hook.txt b/Documentation/howto/rebuild-from-update-hook.txt index 8d55dfbfae..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 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 865a666324..8c32da6deb 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 @@ -85,7 +85,7 @@ Fortunately I did not have to; what I have in the current branch ------------------------------------------------ $ git checkout master -$ git merge revert-c99 ;# this should be a fast forward +$ git merge revert-c99 ;# this should be a fast-forward Updating from 10d781b9caa4f71495c7b34963bef137216f86a8 to e3a693c... cache.h | 8 ++++---- commit.c | 2 +- @@ -95,7 +95,7 @@ Updating from 10d781b9caa4f71495c7b34963bef137216f86a8 to e3a693c... 5 files changed, 8 insertions(+), 8 deletions(-) ------------------------------------------------ -There is no need to redo the test at this point. We fast forwarded +There is no need to redo the test at this point. We fast-forwarded and we know 'master' matches 'revert-c99' exactly. In fact: ------------------------------------------------ diff --git a/Documentation/howto/separating-topic-branches.txt b/Documentation/howto/separating-topic-branches.txt index 0d73b31224..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. 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..b7f8d416d6 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/*) @@ -76,11 +76,11 @@ case "$1" in if expr "$2" : '0*$' >/dev/null; then info "The branch '$1' is new..." else - # updating -- make sure it is a fast forward + # updating -- make sure it is a fast-forward 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/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. |