summaryrefslogtreecommitdiff
path: root/Documentation/howto
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/howto')
-rw-r--r--Documentation/howto/coordinate-embargoed-releases.txt131
-rw-r--r--Documentation/howto/keep-canonical-history-correct.txt216
-rw-r--r--Documentation/howto/maintain-git.txt128
-rw-r--r--Documentation/howto/new-command.txt26
-rw-r--r--Documentation/howto/rebase-from-internal-branch.txt38
-rw-r--r--Documentation/howto/rebuild-from-update-hook.txt12
-rw-r--r--Documentation/howto/recover-corrupted-blob-object.txt10
-rw-r--r--Documentation/howto/recover-corrupted-object-harder.txt479
-rw-r--r--Documentation/howto/revert-a-faulty-merge.txt30
-rw-r--r--Documentation/howto/revert-branch-rebase.txt38
-rw-r--r--Documentation/howto/separating-topic-branches.txt2
-rw-r--r--Documentation/howto/setup-git-server-over-http.txt32
-rw-r--r--Documentation/howto/update-hook-example.txt8
-rw-r--r--Documentation/howto/use-git-daemon.txt2
-rw-r--r--Documentation/howto/using-merge-subtree.txt2
-rw-r--r--Documentation/howto/using-signed-tag-in-pull-request.txt4
16 files changed, 1010 insertions, 148 deletions
diff --git a/Documentation/howto/coordinate-embargoed-releases.txt b/Documentation/howto/coordinate-embargoed-releases.txt
new file mode 100644
index 0000000000..601aae88e9
--- /dev/null
+++ b/Documentation/howto/coordinate-embargoed-releases.txt
@@ -0,0 +1,131 @@
+Content-type: text/asciidoc
+Abstract: When a critical vulnerability is discovered and fixed, we follow this
+ script to coordinate a public release.
+
+How we coordinate embargoed releases
+====================================
+
+To protect Git users from critical vulnerabilities, we do not just release
+fixed versions like regular maintenance releases. Instead, we coordinate
+releases with packagers, keeping the fixes under an embargo until the release
+date. That way, users will have a chance to upgrade on that date, no matter
+what Operating System or distribution they run.
+
+Open a Security Advisory draft
+------------------------------
+
+The first step is to https://github.com/git/git/security/advisories/new[open an
+advisory]. Technically, it is not necessary, but it is convenient and saves a
+bit of hassle. This advisory can also be used to obtain the CVE number and it
+will give us a private fork associated with it that can be used to collaborate
+on a fix.
+
+Release date of the embargoed version
+-------------------------------------
+
+If the vulnerability affects Windows users, we want to have our friends over at
+Visual Studio on board. This means we need to target a "Patch Tuesday" (i.e. a
+second Tuesday of the month), at the minimum three weeks from heads-up to
+coordinated release.
+
+If the vulnerability affects the server side, or can benefit from scans on the
+server side (i.e. if `git fsck` can detect an attack), it is important to give
+all involved Git repository hosting sites enough time to scan all of those
+repositories.
+
+Notifying the Linux distributions
+---------------------------------
+
+At most two weeks before release date, we need to send a notification to
+distros@vs.openwall.org, preferably less than 7 days before the release date.
+This will reach most (all?) Linux distributions. See an example below, and the
+guidelines for this mailing list at
+https://oss-security.openwall.org/wiki/mailing-lists/distros#how-to-use-the-lists[here].
+
+Once the version has been published, we send a note about that to oss-security.
+As an example, see https://www.openwall.com/lists/oss-security/2019/12/13/1[the
+v2.24.1 mail];
+https://oss-security.openwall.org/wiki/mailing-lists/oss-security[Here] are
+their guidelines.
+
+The mail to oss-security should also describe the exploit, and give credit to
+the reporter(s): security researchers still receive too little respect for the
+invaluable service they provide, and public credit goes a long way to keep them
+paid by their respective organizations.
+
+Technically, describing any exploit can be delayed up to 7 days, but we usually
+refrain from doing that, including it right away.
+
+As a courtesy we typically attach a Git bundle (as `.tar.xz` because the list
+will drop `.bundle` attachments) in the mail to distros@ so that the involved
+parties can take care of integrating/backporting them. This bundle is typically
+created using a command like this:
+
+ git bundle create cve-xxx.bundle ^origin/master vA.B.C vD.E.F
+ tar cJvf cve-xxx.bundle.tar.xz cve-xxx.bundle
+
+Example mail to distros@vs.openwall.org
+---------------------------------------
+
+....
+To: distros@vs.openwall.org
+Cc: git-security@googlegroups.com, <other people involved in the report/fix>
+Subject: [vs] Upcoming Git security fix release
+
+Team,
+
+The Git project will release new versions on <date> at 10am Pacific Time or
+soon thereafter. I have attached a Git bundle (embedded in a `.tar.xz` to avoid
+it being dropped) which you can fetch into a clone of
+https://github.com/git/git via `git fetch --tags /path/to/cve-xxx.bundle`,
+containing the tags for versions <versions>.
+
+You can verify with `git tag -v <tag>` that the versions were signed by
+the Git maintainer, using the same GPG key as e.g. v2.24.0.
+
+Please use these tags to prepare `git` packages for your various
+distributions, using the appropriate tagged versions. The added test cases
+help verify the correctness.
+
+The addressed issues are:
+
+<list of CVEs with a short description, typically copy/pasted from Git's
+release notes, usually demo exploit(s), too>
+
+Credit for finding the vulnerability goes to <reporter>, credit for fixing
+it goes to <developer>.
+
+Thanks,
+<name>
+
+....
+
+Example mail to oss-security@lists.openwall.com
+-----------------------------------------------
+
+....
+To: oss-security@lists.openwall.com
+Cc: git-security@googlegroups.com, <other people involved in the report/fix>
+Subject: git: <copy from security advisory>
+
+Team,
+
+The Git project released new versions on <date>, addressing <CVE>.
+
+All supported platforms are affected in one way or another, and all Git
+versions all the way back to <version> are affected. The fixed versions are:
+<versions>.
+
+Link to the announcement: <link to lore.kernel.org/git>
+
+We highly recommend to upgrade.
+
+The addressed issues are:
+* <list of CVEs and their explanations, along with demo exploits>
+
+Credit for finding the vulnerability goes to <reporter>, credit for fixing
+it goes to <developer>.
+
+Thanks,
+<name>
+....
diff --git a/Documentation/howto/keep-canonical-history-correct.txt b/Documentation/howto/keep-canonical-history-correct.txt
new file mode 100644
index 0000000000..35d48ef714
--- /dev/null
+++ b/Documentation/howto/keep-canonical-history-correct.txt
@@ -0,0 +1,216 @@
+From: Junio C Hamano <gitster@pobox.com>
+Date: Wed, 07 May 2014 13:15:39 -0700
+Subject: Beginner question on "Pull is mostly evil"
+Abstract: This how-to explains a method for keeping a
+ project's history correct when using git pull.
+Content-type: text/asciidoc
+
+Keep authoritative canonical history correct with git pull
+==========================================================
+
+Sometimes a new project integrator will end up with project history
+that appears to be "backwards" from what other project developers
+expect. This howto presents a suggested integration workflow for
+maintaining a central repository.
+
+Suppose that that central repository has this history:
+
+------------
+ ---o---o---A
+------------
+
+which ends at commit `A` (time flows from left to right and each node
+in the graph is a commit, lines between them indicating parent-child
+relationship).
+
+Then you clone it and work on your own commits, which leads you to
+have this history in *your* repository:
+
+------------
+ ---o---o---A---B---C
+------------
+
+Imagine your coworker did the same and built on top of `A` in *his*
+repository in the meantime, and then pushed it to the
+central repository:
+
+------------
+ ---o---o---A---X---Y---Z
+------------
+
+Now, if you `git push` at this point, because your history that leads
+to `C` lacks `X`, `Y` and `Z`, it will fail. You need to somehow make
+the tip of your history a descendant of `Z`.
+
+One suggested way to solve the problem is "fetch and then merge", aka
+`git pull`. When you fetch, your repository will have a history like
+this:
+
+------------
+ ---o---o---A---B---C
+ \
+ X---Y---Z
+------------
+
+Once you run merge after that, while still on *your* branch, i.e. `C`,
+you will create a merge `M` and make the history look like this:
+
+------------
+ ---o---o---A---B---C---M
+ \ /
+ X---Y---Z
+------------
+
+`M` is a descendant of `Z`, so you can push to update the central
+repository. Such a merge `M` does not lose any commit in both
+histories, so in that sense it may not be wrong, but when people want
+to talk about "the authoritative canonical history that is shared
+among the project participants", i.e. "the trunk", they often view
+it as "commits you see by following the first-parent chain", and use
+this command to view it:
+
+------------
+ $ git log --first-parent
+------------
+
+For all other people who observed the central repository after your
+coworker pushed `Z` but before you pushed `M`, the commit on the trunk
+used to be `o-o-A-X-Y-Z`. But because you made `M` while you were on
+`C`, `M`'s first parent is `C`, so by pushing `M` to advance the
+central repository, you made `X-Y-Z` a side branch, not on the trunk.
+
+You would rather want to have a history of this shape:
+
+------------
+ ---o---o---A---X---Y---Z---M'
+ \ /
+ B-----------C
+------------
+
+so that in the first-parent chain, it is clear that the project first
+did `X` and then `Y` and then `Z` and merged a change that consists of
+two commits `B` and `C` that achieves a single goal. You may have
+worked on fixing the bug #12345 with these two patches, and the merge
+`M'` with swapped parents can say in its log message "Merge
+fix-bug-12345". Having a way to tell `git pull` to create a merge
+but record the parents in reverse order may be a way to do so.
+
+Note that I said "achieves a single goal" above, because this is
+important. "Swapping the merge order" only covers a special case
+where the project does not care too much about having unrelated
+things done on a single merge but cares a lot about first-parent
+chain.
+
+There are multiple schools of thought about the "trunk" management.
+
+ 1. Some projects want to keep a completely linear history without any
+ merges. Obviously, swapping the merge order would not match their
+ taste. You would need to flatten your history on top of the
+ updated upstream to result in a history of this shape instead:
++
+------------
+ ---o---o---A---X---Y---Z---B---C
+------------
++
+with `git pull --rebase` or something.
+
+ 2. Some projects tolerate merges in their history, but do not worry
+ too much about the first-parent order, and allow fast-forward
+ merges. To them, swapping the merge order does not hurt, but
+ it is unnecessary.
+
+ 3. Some projects want each commit on the "trunk" to do one single
+ thing. The output of `git log --first-parent` in such a project
+ would show either a merge of a side branch that completes a single
+ theme, or a single commit that completes a single theme by itself.
+ If your two commits `B` and `C` (or they may even be two groups of
+ commits) were solving two independent issues, then the merge `M'`
+ we made in the earlier example by swapping the merge order is
+ still not up to the project standard. It merges two unrelated
+ efforts `B` and `C` at the same time.
+
+For projects in the last category (Git itself is one of them),
+individual developers would want to prepare a history more like
+this:
+
+------------
+ C0--C1--C2 topic-c
+ /
+ ---o---o---A master
+ \
+ B0--B1--B2 topic-b
+------------
+
+That is, keeping separate topics on separate branches, perhaps like
+so:
+
+------------
+ $ git clone $URL work && cd work
+ $ git checkout -b topic-b master
+ $ ... work to create B0, B1 and B2 to complete one theme
+ $ git checkout -b topic-c master
+ $ ... same for the theme of topic-c
+------------
+
+And then
+
+------------
+ $ git checkout master
+ $ git pull --ff-only
+------------
+
+would grab `X`, `Y` and `Z` from the upstream and advance your master
+branch:
+
+------------
+ C0--C1--C2 topic-c
+ /
+ ---o---o---A---X---Y---Z master
+ \
+ B0--B1--B2 topic-b
+------------
+
+And then you would merge these two branches separately:
+
+------------
+ $ git merge topic-b
+ $ git merge topic-c
+------------
+
+to result in
+
+------------
+ C0--C1---------C2
+ / \
+ ---o---o---A---X---Y---Z---M---N
+ \ /
+ B0--B1-----B2
+------------
+
+and push it back to the central repository.
+
+It is very much possible that while you are merging topic-b and
+topic-c, somebody again advanced the history in the central repository
+to put `W` on top of `Z`, and make your `git push` fail.
+
+In such a case, you would rewind to discard `M` and `N`, update the
+tip of your 'master' again and redo the two merges:
+
+------------
+ $ git reset --hard origin/master
+ $ git pull --ff-only
+ $ git merge topic-b
+ $ git merge topic-c
+------------
+
+The procedure will result in a history that looks like this:
+
+------------
+ C0--C1--------------C2
+ / \
+ ---o---o---A---X---Y---Z---W---M'--N'
+ \ /
+ B0--B1---------B2
+------------
+
+See also http://git-blame.blogspot.com/2013/09/fun-with-first-parent-history.html
diff --git a/Documentation/howto/maintain-git.txt b/Documentation/howto/maintain-git.txt
index 816c791502..a67130debb 100644
--- a/Documentation/howto/maintain-git.txt
+++ b/Documentation/howto/maintain-git.txt
@@ -1,7 +1,7 @@
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
+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.
@@ -13,7 +13,7 @@ How to maintain Git
Activities
----------
-The maintainer's git time is spent on three activities.
+The maintainer's Git time is spent on three activities.
- Communication (45%)
@@ -39,26 +39,26 @@ 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.
- - Feature releases are numbered as vX.Y.Z and are meant to
+ - Feature releases are numbered as vX.Y.0 and are meant to
contain bugfixes and enhancements in any area, including
functionality, performance and usability, without regression.
- One release cycle for a feature release is expected to last for
eight to ten weeks.
- - 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).
+ - Maintenance releases are numbered as vX.Y.Z and are meant
+ to contain only bugfixes for the corresponding vX.Y.0 feature
+ release and earlier maintenance releases vX.Y.W (W < Z).
- '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.
+ branch is tagged with vX.Y.0.
- 'maint' branch is used to prepare for the next maintenance
- release. After the feature release vX.Y.Z is made, the tip
+ release. After the feature release vX.Y.0 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.
+ branch is tagged with vX.Y.1, vX.Y.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
@@ -66,7 +66,7 @@ this mailing list after each feature release is made.
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
+ - 'seen' branch is used to publish other proposed changes that do
not yet pass the criteria set for 'next'.
- The tips of 'master' and 'maint' branches will not be rewound to
@@ -76,7 +76,7 @@ this mailing list after each feature release is made.
of the cycle.
- Usually 'master' contains all of 'maint' and 'next' contains all
- of 'master'. 'pu' contains all the topics merged to 'next', but
+ of 'master'. 'seen' contains all the topics merged to 'next', but
is rebuilt directly on 'master'.
- The tip of 'master' is meant to be more stable than any
@@ -86,11 +86,15 @@ this mailing list after each feature release is made.
users are encouraged to test it so that regressions and bugs
are found before new topics are merged to 'master'.
+Note that before v1.9.0 release, the version numbers used to be
+structured slightly differently. vX.Y.Z were feature releases while
+vX.Y.Z.W were maintenance releases for vX.Y.Z.
+
A Typical Git Day
-----------------
-A typical git day for the maintainer implements the above policy
+A typical Git day for the maintainer implements the above policy
by doing the following:
- Scan mailing list. Respond with review comments, suggestions
@@ -150,15 +154,17 @@ by doing the following:
- 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
+ is forked from the tip of 'master' (or the last feature release,
+ which is a bit older than 'master'). This includes both
enhancements and unobvious fixes to 'master'. A topic
branch is named as ai/topic where "ai" is two-letter string
named after 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.
+ topic branch that is forked from the tip of 'maint' (or the
+ oldest and still relevant maintenance branch). The
+ topic may be named as ai/maint-topic.
- Changes that pertain to an existing topic are applied to
the branch, but:
@@ -170,24 +176,40 @@ by doing the following:
- Replacement patches to an existing topic are accepted only
for commits not in 'next'.
- The above except the "replacement" are all done with:
+ The initial round is done with:
$ git checkout ai/topic ;# or "git checkout -b ai/topic master"
$ git am -sc3 mailbox
- while patch replacement is often done by:
+ and replacing an existing topic with subsequent round is done with:
+
+ $ git checkout master...ai/topic ;# try to reapply to the same base
+ $ git am -sc3 mailbox
+
+ to prepare the new round on a detached HEAD, and then
- $ git format-patch ai/topic~$n..ai/topic ;# export existing
+ $ git range-diff @{-1}...
+ $ git diff @{-1}
- then replace some parts with the new patch, and reapplying:
+ to double check what changed since the last round, and finally
- $ git checkout ai/topic
- $ git reset --hard ai/topic~$n
- $ git am -sc3 -s 000*.txt
+ $ git checkout -B @{-1}
+
+ to conclude (the last step is why a topic already in 'next' is
+ not replaced but updated incrementally).
+
+ Whether it is the initial round or a subsequent round, the topic
+ may not build even in isolation, or may break the build when
+ merged to integration branches due to bugs. There may already
+ be obvious and trivial improvements suggested on the list. The
+ maintainer often adds an extra commit, with "SQUASH???" in its
+ title, to fix things up, before publishing the integration
+ branches to make it usable by other developers for testing.
+ These changes are what the maintainer is not 100% committed to
+ (trivial typofixes etc. are often squashed directly into the
+ patches that need fixing, without being applied as a separate
+ "SQUASH???" commit), so that they can be removed easily as needed.
- The full test suite is always run for 'maint' and 'master'
- after patch application; for topic branches the tests are run
- as time permits.
- Merge maint to master as needed:
@@ -207,12 +229,12 @@ by doing the following:
series?)
- Prepare 'jch' branch, which is used to represent somewhere
- between 'master' and 'pu' and often is slightly ahead of 'next'.
+ between 'master' and 'seen' and often is slightly ahead of 'next'.
- $ Meta/Reintegrate master..pu >Meta/redo-jch.sh
+ $ Meta/Reintegrate master..seen >Meta/redo-jch.sh
The result is a script that lists topics to be merged in order to
- rebuild 'pu' as the input to Meta/Reintegrate script. Remove
+ rebuild 'seen' as the input to Meta/Reintegrate script. Remove
later topics that should not be in 'jch' yet. Add a line that
consists of '### match next' before the name of the first topic
in the output that should be in 'jch' but not in 'next' yet.
@@ -269,29 +291,29 @@ by doing the following:
merged to 'master'. This may lose '### match next' marker;
add it again to the appropriate place when it happens.
- - Rebuild 'pu'.
+ - Rebuild 'seen'.
- $ Meta/Reintegrate master..pu >Meta/redo-pu.sh
+ $ Meta/Reintegrate master..seen >Meta/redo-seen.sh
- Edit the result by adding new topics that are not still in 'pu'
+ Edit the result by adding new topics that are not still in 'seen'
in the script. Then
- $ git checkout -B pu jch
- $ sh Meta/redo-pu.sh
+ $ git checkout -B seen jch
+ $ sh Meta/redo-seen.sh
- When all is well, clean up the redo-pu.sh script with
+ When all is well, clean up the redo-seen.sh script with
- $ sh Meta/redo-pu.sh -u
+ $ sh Meta/redo-seen.sh -u
Double check by running
- $ git branch --no-merged pu
+ $ git branch --no-merged seen
to see there is no unexpected leftover topics.
At this point, build-test the result for semantic conflicts, and
if there are, prepare an appropriate merge-fix first (see
- appendix), and rebuild the 'pu' branch from scratch, starting at
+ appendix), and rebuild the 'seen' branch from scratch, starting at
the tip of 'jch'.
- Update "What's cooking" message to review the updates to
@@ -301,14 +323,14 @@ by doing the following:
$ Meta/cook
- This script inspects the history between master..pu, finds tips
+ This script inspects the history between master..seen, finds tips
of topic branches, compares what it found with the current
contents in Meta/whats-cooking.txt, and updates that file.
- Topics not listed in the file but are found in master..pu are
+ Topics not listed in the file but are found in master..seen are
added to the "New topics" section, topics listed in the file that
- are no longer found in master..pu are moved to the "Graduated to
+ are no longer found in master..seen are moved to the "Graduated to
master" section, and topics whose commits changed their states
- (e.g. used to be only in 'pu', now merged to 'next') are updated
+ (e.g. used to be only in 'seen', now merged to 'next') are updated
with change markers "<<" and ">>".
Look for lines enclosed in "<<" and ">>"; they hold contents from
@@ -338,7 +360,7 @@ Observations
Some observations to be made.
* Each topic is tested individually, and also together with other
- topics cooking first in 'pu', then in 'jch' and then in 'next'.
+ topics cooking first in 'seen', then in 'jch' and then in 'next'.
Until it matures, no part of it is merged to 'master'.
* A topic already in 'next' can get fixes while still in
@@ -367,6 +389,14 @@ Some observations to be made.
be included in the next feature release. Being in the
'master' branch typically is.
+ * Due to the nature of "SQUASH???" fix-ups, if the original author
+ agrees with the suggested changes, it is OK to squash them to
+ appropriate patches in the next round (when the suggested change
+ is small enough, the author should not even bother with
+ "Helped-by"). It is also OK to drop them from the next round
+ when the original author does not agree with the suggestion, but
+ the author is expected to say why somewhere in the discussion.
+
Appendix
--------
@@ -381,7 +411,7 @@ new use of the variable under its old name. When these two topics
are merged together, the reference to the variable newly added by
the latter topic will still use the old name in the result.
-The Meta/Reintegrate script that is used by redo-jch and redo-pu
+The Meta/Reintegrate script that is used by redo-jch and redo-seen
scripts implements a crude but usable way to work this issue around.
When the script merges branch $X, it checks if "refs/merge-fix/$X"
exists, and if so, the effect of it is squashed into the result of
@@ -401,14 +431,14 @@ commit that can be squashed into a result of mechanical merge to
correct semantic conflicts.
After finding that the result of merging branch "ai/topic" to an
-integration branch had such a semantic conflict, say pu~4, check the
+integration branch had such a semantic conflict, say seen~4, check the
problematic merge out on a detached HEAD, edit the working tree to
fix the semantic conflict, and make a separate commit to record the
fix-up:
- $ git checkout pu~4
+ $ git checkout seen~4
$ git show -s --pretty=%s ;# double check
- Merge branch 'ai/topic' to pu
+ Merge branch 'ai/topic' to seen
$ edit
$ git commit -m 'merge-fix/ai/topic' -a
@@ -420,9 +450,9 @@ result:
Then double check the result by asking Meta/Reintegrate to redo the
merge:
- $ git checkout pu~5 ;# the parent of the problem merge
+ $ git checkout seen~5 ;# the parent of the problem merge
$ echo ai/topic | Meta/Reintegrate
- $ git diff pu~4
+ $ git diff seen~4
This time, because you prepared refs/merge-fix/ai/topic, the
resulting merge should have been tweaked to include the fix for the
@@ -434,7 +464,7 @@ branch needs this merge-fix is because another branch merged earlier
to the integration branch changed the underlying assumption ai/topic
branch made (e.g. ai/topic branch added a site to refer to a
variable, while the other branch renamed that variable and adjusted
-existing use sites), and if you changed redo-jch (or redo-pu) script
+existing use sites), and if you changed redo-jch (or redo-seen) script
to merge ai/topic branch before the other branch, then the above
merge-fix should not be applied while merging ai/topic, but should
instead be applied while merging the other branch. You would need
diff --git a/Documentation/howto/new-command.txt b/Documentation/howto/new-command.txt
index 36502f6718..15a4c8031f 100644
--- a/Documentation/howto/new-command.txt
+++ b/Documentation/howto/new-command.txt
@@ -1,25 +1,25 @@
From: Eric S. Raymond <esr@thyrsus.com>
Abstract: This is how-to documentation for people who want to add extension
- commands to git. It should be read alongside api-builtin.txt.
+ commands to Git. It should be read alongside api-builtin.txt.
Content-type: text/asciidoc
How to integrate new subcommands
================================
This is how-to documentation for people who want to add extension
-commands to git. It should be read alongside api-builtin.txt.
+commands to Git. It should be read alongside api-builtin.txt.
Runtime environment
-------------------
-git subcommands are standalone executables that live in the git exec
+Git subcommands are standalone executables that live in the Git exec
path, normally /usr/lib/git-core. The git executable itself is a
thin wrapper that knows where the subcommands live, and runs them by
passing command-line arguments to them.
-(If "git foo" is not found in the git exec path, the wrapper
+(If "git foo" is not found in the Git exec path, the wrapper
will look in the rest of your $PATH for it. Thus, it's possible
-to write local git extensions that don't live in system space.)
+to write local Git extensions that don't live in system space.)
Implementation languages
------------------------
@@ -30,13 +30,13 @@ Perl.
While we strongly encourage coding in portable C for portability,
these specific scripting languages are also acceptable. We won't
accept more without a very strong technical case, as we don't want
-to broaden the git suite's required dependencies. Import utilities,
+to broaden the Git suite's required dependencies. Import utilities,
surgical tools, remote helpers and other code at the edges of the
-git suite are more lenient and we allow Python (and even Tcl/tk),
+Git suite are more lenient and we allow Python (and even Tcl/tk),
but they should not be used for core functions.
This may change in the future. Especially Python is not allowed in
-core because we need better Python integration in the git Windows
+core because we need better Python integration in the Git Windows
installer before we can be confident people in that environment
won't experience an unacceptably large loss of capability.
@@ -54,7 +54,7 @@ functions available to built-in commands written in C.
What every extension command needs
----------------------------------
-You must have a man page, written in asciidoc (this is what git help
+You must have a man page, written in asciidoc (this is what Git help
followed by your subcommand name will display). Be aware that there is
a local asciidoc configuration and macros which you should use. It's
often helpful to start by cloning an existing page and replacing the
@@ -74,7 +74,7 @@ Integrating a command
---------------------
Here are the things you need to do when you want to merge a new
-subcommand into the git tree.
+subcommand into the Git tree.
1. Don't forget to sign off your patch!
@@ -94,8 +94,10 @@ your language, document it in the INSTALL file.
6. There is a file command-list.txt in the distribution main directory
that categorizes commands by type, so they can be listed in appropriate
subsections in the documentation's summary command list. Add an entry
-for yours. To understand the categories, look at git-cmmands.txt
-in the main directory.
+for yours. To understand the categories, look at command-list.txt
+in the main directory. If the new command is part of the typical Git
+workflow and you believe it common enough to be mentioned in 'git help',
+map this command to a common group in the column [common].
7. Give the maintainer one paragraph to include in the RelNotes file
to describe the new feature; a good place to do so is in the cover
diff --git a/Documentation/howto/rebase-from-internal-branch.txt b/Documentation/howto/rebase-from-internal-branch.txt
index 4627ee47f2..f2e10a7ec8 100644
--- a/Documentation/howto/rebase-from-internal-branch.txt
+++ b/Documentation/howto/rebase-from-internal-branch.txt
@@ -4,7 +4,7 @@ Cc: Petr Baudis <pasky@suse.cz>, Linus Torvalds <torvalds@osdl.org>
Subject: Re: sending changesets from the middle of a git tree
Date: Sun, 14 Aug 2005 18:37:39 -0700
Abstract: In this article, JC talks about how he rebases the
- public "pu" branch using the core GIT tools when he updates
+ public "seen" branch using the core Git tools when he updates
the "master" branch, and how "rebase" works. Also discussed
is how this applies to individual developers who sends patches
upstream.
@@ -20,8 +20,8 @@ Petr Baudis <pasky@suse.cz> writes:
> 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"
->> > branch to the real branches.
+>> > Junio, maybe you want to talk about how you move patches from your
+>> > "seen" branch to the real branches.
>>
> Actually, wouldn't this be also precisely for what StGIT is intended to?
--------------------------------------
@@ -31,14 +31,14 @@ up. With its basing philosophical ancestry on quilt, this is
the kind of task StGIT is designed to do.
I just have done a simpler one, this time using only the core
-GIT tools.
+Git tools.
-I had a handful of commits that were ahead of master in pu, and I
+I had a handful of commits that were ahead of master in 'seen', and I
wanted to add some documentation bypassing my usual habit of
-placing new things in pu first. At the beginning, the commit
+placing new things in 'seen' first. At the beginning, the commit
ancestry graph looked like this:
- *"pu" head
+ *"seen" head
master --> #1 --> #2 --> #3
So I started from master, made a bunch of edits, and committed:
@@ -50,7 +50,7 @@ So I started from master, made a bunch of edits, and committed:
After the commit, the ancestry graph would look like this:
- *"pu" head
+ *"seen" head
master^ --> #1 --> #2 --> #3
\
\---> master
@@ -58,31 +58,31 @@ After the commit, the ancestry graph would look like this:
The old master is now master^ (the first parent of the master).
The new master commit holds my documentation updates.
-Now I have to deal with "pu" branch.
+Now I have to deal with "seen" branch.
This is the kind of situation I used to have all the time when
Linus was the maintainer and I was a contributor, when you look
-at "master" branch being the "maintainer" branch, and "pu"
+at "master" branch being the "maintainer" branch, and "seen"
branch being the "contributor" branch. Your work started at the
tip of the "maintainer" branch some time ago, you made a lot of
progress in the meantime, and now the maintainer branch has some
other commits you do not have yet. And "git rebase" was written
with the explicit purpose of helping to maintain branches like
-"pu". You _could_ merge master to pu and keep going, but if you
+"seen". You _could_ merge master to 'seen' and keep going, but if you
eventually want to cherrypick and merge some but not necessarily
all changes back to the master branch, it often makes later
operations for _you_ easier if you rebase (i.e. carry forward
-your changes) "pu" rather than merge. So I ran "git rebase":
+your changes) "seen" rather than merge. So I ran "git rebase":
- $ git checkout pu
- $ git rebase master pu
+ $ git checkout seen
+ $ git rebase master seen
What this does is to pick all the commits since the current
-branch (note that I now am on "pu" branch) forked from the
+branch (note that I now am on "seen" branch) forked from the
master branch, and forward port these changes.
master^ --> #1 --> #2 --> #3
- \ *"pu" head
+ \ *"seen" head
\---> master --> #1' --> #2' --> #3'
The diff between master^ and #1 is applied to master and
@@ -92,11 +92,11 @@ commits are made similarly out of #2 and #3 commits.
Old #3 is not recorded in any of the .git/refs/heads/ file
anymore, so after doing this you will have dangling commit if
-you ran fsck-cache, which is normal. After testing "pu", you
+you ran fsck-cache, which is normal. After testing "seen", you
can run "git prune" to get rid of those original three commits.
While I am talking about "git rebase", I should talk about how
-to do cherrypicking using only the core GIT tools.
+to do cherrypicking using only the core Git tools.
Let's go back to the earlier picture, with different labels.
@@ -139,7 +139,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 or .git/refs/heads/master.
You run "git rebase" now.
$ git rebase FETCH_HEAD master
diff --git a/Documentation/howto/rebuild-from-update-hook.txt b/Documentation/howto/rebuild-from-update-hook.txt
index 00c1b45b79..db219f5c07 100644
--- a/Documentation/howto/rebuild-from-update-hook.txt
+++ b/Documentation/howto/rebuild-from-update-hook.txt
@@ -3,23 +3,23 @@ Message-ID: <7vy86o6usx.fsf@assigned-by-dhcp.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
- shown at http://www.kernel.org/pub/software/scm/git/docs/.
+ uses the post-update hook to automate Git documentation page
+ shown at https://www.kernel.org/pub/software/scm/git/docs/.
Content-type: text/asciidoc
How to rebuild from update hook
===============================
-The pages under http://www.kernel.org/pub/software/scm/git/docs/
+The pages under https://www.kernel.org/pub/software/scm/git/docs/
are built from Documentation/ directory of the git.git project
and needed to be kept up-to-date. The www.kernel.org/ servers
are mirrored and I was told that the origin of the mirror is on
the machine $some.kernel.org, on which I was given an account
-when I took over git maintainership from Linus.
+when I took over Git maintainership from Linus.
The directories relevant to this how-to are these two:
- /pub/scm/git/git.git/ The public git repository.
+ /pub/scm/git/git.git/ The public Git repository.
/pub/software/scm/git/docs/ The HTML documentation page.
So I made a repository to generate the documentation under my
@@ -46,7 +46,7 @@ script:
EOF
Initially I used to run this by hand whenever I push into the
-public git repository. Then I did a cron job that ran twice a
+public Git repository. Then I did a cron job that ran twice a
day. The current round uses the post-update hook mechanism,
like this:
diff --git a/Documentation/howto/recover-corrupted-blob-object.txt b/Documentation/howto/recover-corrupted-blob-object.txt
index 7484735320..1b3b188d3c 100644
--- a/Documentation/howto/recover-corrupted-blob-object.txt
+++ b/Documentation/howto/recover-corrupted-blob-object.txt
@@ -15,12 +15,12 @@ On Fri, 9 Nov 2007, Yossi Leybovich wrote:
> 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
+So exactly *because* the SHA-1 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
+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).
@@ -44,7 +44,7 @@ So:
-----------------------------------------------------------
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 ;).
+it's full SHA-1 name (you just dropped the "4b" from the result ;).
Let's see what that tells us:
@@ -89,7 +89,7 @@ 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!
+again, and if it outputs the missing SHA-1 (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?
@@ -134,7 +134,7 @@ and your repository is good again!
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
+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
diff --git a/Documentation/howto/recover-corrupted-object-harder.txt b/Documentation/howto/recover-corrupted-object-harder.txt
new file mode 100644
index 0000000000..8994e2559e
--- /dev/null
+++ b/Documentation/howto/recover-corrupted-object-harder.txt
@@ -0,0 +1,479 @@
+Date: Wed, 16 Oct 2013 04:34:01 -0400
+From: Jeff King <peff@peff.net>
+Subject: pack corruption post-mortem
+Abstract: Recovering a corrupted object when no good copy is available.
+Content-type: text/asciidoc
+
+How to recover an object from scratch
+=====================================
+
+I was recently presented with a repository with a corrupted packfile,
+and was asked if the data was recoverable. This post-mortem describes
+the steps I took to investigate and fix the problem. I thought others
+might find the process interesting, and it might help somebody in the
+same situation.
+
+********************************
+Note: In this case, no good copy of the repository was available. For
+the much easier case where you can get the corrupted object from
+elsewhere, see link:recover-corrupted-blob-object.html[this howto].
+********************************
+
+I started with an fsck, which found a problem with exactly one object
+(I've used $pack and $obj below to keep the output readable, and also
+because I'll refer to them later):
+
+-----------
+ $ git fsck
+ error: $pack SHA1 checksum mismatch
+ error: index CRC mismatch for object $obj from $pack at offset 51653873
+ error: inflate: data stream error (incorrect data check)
+ error: cannot unpack $obj from $pack at offset 51653873
+-----------
+
+The pack checksum failing means a byte is munged somewhere, and it is
+presumably in the object mentioned (since both the index checksum and
+zlib were failing).
+
+Reading the zlib source code, I found that "incorrect data check" means
+that the adler-32 checksum at the end of the zlib data did not match the
+inflated data. So stepping the data through zlib would not help, as it
+did not fail until the very end, when we realize the CRC does not match.
+The problematic bytes could be anywhere in the object data.
+
+The first thing I did was pull the broken data out of the packfile. I
+needed to know how big the object was, which I found out with:
+
+------------
+ $ git show-index <$idx | cut -d' ' -f1 | sort -n | grep -A1 51653873
+ 51653873
+ 51664736
+------------
+
+Show-index gives us the list of objects and their offsets. We throw away
+everything but the offsets, and then sort them so that our interesting
+offset (which we got from the fsck output above) is followed immediately
+by the offset of the next object. Now we know that the object data is
+10863 bytes long, and we can grab it with:
+
+------------
+ dd if=$pack of=object bs=1 skip=51653873 count=10863
+------------
+
+I inspected a hexdump of the data, looking for any obvious bogosity
+(e.g., a 4K run of zeroes would be a good sign of filesystem
+corruption). But everything looked pretty reasonable.
+
+Note that the "object" file isn't fit for feeding straight to zlib; it
+has the git packed object header, which is variable-length. We want to
+strip that off so we can start playing with the zlib data directly. You
+can either work your way through it manually (the format is described in
+link:../technical/pack-format.html[Documentation/technical/pack-format.txt]),
+or you can walk through it in a debugger. I did the latter, creating a
+valid pack like:
+
+------------
+ # pack magic and version
+ printf 'PACK\0\0\0\2' >tmp.pack
+ # pack has one object
+ printf '\0\0\0\1' >>tmp.pack
+ # now add our object data
+ cat object >>tmp.pack
+ # and then append the pack trailer
+ /path/to/git.git/t/helper/test-tool sha1 -b <tmp.pack >trailer
+ cat trailer >>tmp.pack
+------------
+
+and then running "git index-pack tmp.pack" in the debugger (stop at
+unpack_raw_entry). Doing this, I found that there were 3 bytes of header
+(and the header itself had a sane type and size). So I stripped those
+off with:
+
+------------
+ dd if=object of=zlib bs=1 skip=3
+------------
+
+I ran the result through zlib's inflate using a custom C program. And
+while it did report the error, I did get the right number of output
+bytes (i.e., it matched git's size header that we decoded above). But
+feeding the result back to "git hash-object" didn't produce the same
+sha1. So there were some wrong bytes, but I didn't know which. The file
+happened to be C source code, so I hoped I could notice something
+obviously wrong with it, but I didn't. I even got it to compile!
+
+I also tried comparing it to other versions of the same path in the
+repository, hoping that there would be some part of the diff that didn't
+make sense. Unfortunately, this happened to be the only revision of this
+particular file in the repository, so I had nothing to compare against.
+
+So I took a different approach. Working under the guess that the
+corruption was limited to a single byte, I wrote a program to munge each
+byte individually, and try inflating the result. Since the object was
+only 10K compressed, that worked out to about 2.5M attempts, which took
+a few minutes.
+
+The program I used is here:
+
+----------------------------------------------
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+#include <zlib.h>
+
+static int try_zlib(unsigned char *buf, int len)
+{
+ /* make this absurdly large so we don't have to loop */
+ static unsigned char out[1024*1024];
+ z_stream z;
+ int ret;
+
+ memset(&z, 0, sizeof(z));
+ inflateInit(&z);
+
+ z.next_in = buf;
+ z.avail_in = len;
+ z.next_out = out;
+ z.avail_out = sizeof(out);
+
+ ret = inflate(&z, 0);
+ inflateEnd(&z);
+ return ret >= 0;
+}
+
+/* eye candy */
+static int counter = 0;
+static void progress(int sig)
+{
+ fprintf(stderr, "\r%d", counter);
+ alarm(1);
+}
+
+int main(void)
+{
+ /* oversized so we can read the whole buffer in */
+ unsigned char buf[1024*1024];
+ int len;
+ unsigned i, j;
+
+ signal(SIGALRM, progress);
+ alarm(1);
+
+ len = read(0, buf, sizeof(buf));
+ for (i = 0; i < len; i++) {
+ unsigned char c = buf[i];
+ for (j = 0; j <= 0xff; j++) {
+ buf[i] = j;
+
+ counter++;
+ if (try_zlib(buf, len))
+ printf("i=%d, j=%x\n", i, j);
+ }
+ buf[i] = c;
+ }
+
+ alarm(0);
+ fprintf(stderr, "\n");
+ return 0;
+}
+----------------------------------------------
+
+I compiled and ran with:
+
+-------
+ gcc -Wall -Werror -O3 munge.c -o munge -lz
+ ./munge <zlib
+-------
+
+
+There were a few false positives early on (if you write "no data" in the
+zlib header, zlib thinks it's just fine :) ). But I got a hit about
+halfway through:
+
+-------
+ i=5642, j=c7
+-------
+
+I let it run to completion, and got a few more hits at the end (where it
+was munging the CRC to match our broken data). So there was a good
+chance this middle hit was the source of the problem.
+
+I confirmed by tweaking the byte in a hex editor, zlib inflating the
+result (no errors!), and then piping the output into "git hash-object",
+which reported the sha1 of the broken object. Success!
+
+I fixed the packfile itself with:
+
+-------
+ chmod +w $pack
+ printf '\xc7' | dd of=$pack bs=1 seek=51659518 conv=notrunc
+ chmod -w $pack
+-------
+
+The `\xc7` comes from the replacement byte our "munge" program found.
+The offset 51659518 is derived by taking the original object offset
+(51653873), adding the replacement offset found by "munge" (5642), and
+then adding back in the 3 bytes of git header we stripped.
+
+After that, "git fsck" ran clean.
+
+As for the corruption itself, I was lucky that it was indeed a single
+byte. In fact, it turned out to be a single bit. The byte 0xc7 was
+corrupted to 0xc5. So presumably it was caused by faulty hardware, or a
+cosmic ray.
+
+And the aborted attempt to look at the inflated output to see what was
+wrong? I could have looked forever and never found it. Here's the diff
+between what the corrupted data inflates to, versus the real data:
+
+--------------
+ - cp = strtok (arg, "+");
+ + cp = strtok (arg, ".");
+--------------
+
+It tweaked one byte and still ended up as valid, readable C that just
+happened to do something totally different! One takeaway is that on a
+less unlucky day, looking at the zlib output might have actually been
+helpful, as most random changes would actually break the C code.
+
+But more importantly, git's hashing and checksumming noticed a problem
+that easily could have gone undetected in another system. The result
+still compiled, but would have caused an interesting bug (that would
+have been blamed on some random commit).
+
+
+The adventure continues...
+--------------------------
+
+I ended up doing this again! Same entity, new hardware. The assumption
+at this point is that the old disk corrupted the packfile, and then the
+corruption was migrated to the new hardware (because it was done by
+rsync or similar, and no fsck was done at the time of migration).
+
+This time, the affected blob was over 20 megabytes, which was far too
+large to do a brute-force on. I followed the instructions above to
+create the `zlib` file. I then used the `inflate` program below to pull
+the corrupted data from that. Examining that output gave me a hint about
+where in the file the corruption was. But now I was working with the
+file itself, not the zlib contents. So knowing the sha1 of the object
+and the approximate area of the corruption, I used the `sha1-munge`
+program below to brute-force the correct byte.
+
+Here's the inflate program (it's essentially `gunzip` but without the
+`.gz` header processing):
+
+--------------------------
+#include <stdio.h>
+#include <string.h>
+#include <zlib.h>
+#include <stdlib.h>
+
+int main(int argc, char **argv)
+{
+ /*
+ * oversized so we can read the whole buffer in;
+ * this could actually be switched to streaming
+ * to avoid any memory limitations
+ */
+ static unsigned char buf[25 * 1024 * 1024];
+ static unsigned char out[25 * 1024 * 1024];
+ int len;
+ z_stream z;
+ int ret;
+
+ len = read(0, buf, sizeof(buf));
+ memset(&z, 0, sizeof(z));
+ inflateInit(&z);
+
+ z.next_in = buf;
+ z.avail_in = len;
+ z.next_out = out;
+ z.avail_out = sizeof(out);
+
+ ret = inflate(&z, 0);
+ if (ret != Z_OK && ret != Z_STREAM_END)
+ fprintf(stderr, "initial inflate failed (%d)\n", ret);
+
+ fprintf(stderr, "outputting %lu bytes", z.total_out);
+ fwrite(out, 1, z.total_out, stdout);
+ return 0;
+}
+--------------------------
+
+And here is the `sha1-munge` program:
+
+--------------------------
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+#include <openssl/sha.h>
+#include <stdlib.h>
+
+/* eye candy */
+static int counter = 0;
+static void progress(int sig)
+{
+ fprintf(stderr, "\r%d", counter);
+ alarm(1);
+}
+
+static const signed char hexval_table[256] = {
+ -1, -1, -1, -1, -1, -1, -1, -1, /* 00-07 */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* 08-0f */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* 10-17 */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* 18-1f */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* 20-27 */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* 28-2f */
+ 0, 1, 2, 3, 4, 5, 6, 7, /* 30-37 */
+ 8, 9, -1, -1, -1, -1, -1, -1, /* 38-3f */
+ -1, 10, 11, 12, 13, 14, 15, -1, /* 40-47 */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* 48-4f */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* 50-57 */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* 58-5f */
+ -1, 10, 11, 12, 13, 14, 15, -1, /* 60-67 */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* 68-67 */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* 70-77 */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* 78-7f */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* 80-87 */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* 88-8f */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* 90-97 */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* 98-9f */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* a0-a7 */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* a8-af */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* b0-b7 */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* b8-bf */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* c0-c7 */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* c8-cf */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* d0-d7 */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* d8-df */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* e0-e7 */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* e8-ef */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* f0-f7 */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* f8-ff */
+};
+
+static inline unsigned int hexval(unsigned char c)
+{
+return hexval_table[c];
+}
+
+static int get_sha1_hex(const char *hex, unsigned char *sha1)
+{
+ int i;
+ for (i = 0; i < 20; i++) {
+ unsigned int val;
+ /*
+ * hex[1]=='\0' is caught when val is checked below,
+ * but if hex[0] is NUL we have to avoid reading
+ * past the end of the string:
+ */
+ if (!hex[0])
+ return -1;
+ val = (hexval(hex[0]) << 4) | hexval(hex[1]);
+ if (val & ~0xff)
+ return -1;
+ *sha1++ = val;
+ hex += 2;
+ }
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ /* oversized so we can read the whole buffer in */
+ static unsigned char buf[25 * 1024 * 1024];
+ char header[32];
+ int header_len;
+ unsigned char have[20], want[20];
+ int start, len;
+ SHA_CTX orig;
+ unsigned i, j;
+
+ if (!argv[1] || get_sha1_hex(argv[1], want)) {
+ fprintf(stderr, "usage: sha1-munge <sha1> [start] <file.in\n");
+ return 1;
+ }
+
+ if (argv[2])
+ start = atoi(argv[2]);
+ else
+ start = 0;
+
+ len = read(0, buf, sizeof(buf));
+ header_len = sprintf(header, "blob %d", len) + 1;
+ fprintf(stderr, "using header: %s\n", header);
+
+ /*
+ * We keep a running sha1 so that if you are munging
+ * near the end of the file, we do not have to re-sha1
+ * the unchanged earlier bytes
+ */
+ SHA1_Init(&orig);
+ SHA1_Update(&orig, header, header_len);
+ if (start)
+ SHA1_Update(&orig, buf, start);
+
+ signal(SIGALRM, progress);
+ alarm(1);
+
+ for (i = start; i < len; i++) {
+ unsigned char c;
+ SHA_CTX x;
+
+#if 0
+ /*
+ * deletion -- this would not actually work in practice,
+ * I think, because we've already committed to a
+ * particular size in the header. Ditto for addition
+ * below. In those cases, you'd have to do the whole
+ * sha1 from scratch, or possibly keep three running
+ * "orig" sha1 computations going.
+ */
+ memcpy(&x, &orig, sizeof(x));
+ SHA1_Update(&x, buf + i + 1, len - i - 1);
+ SHA1_Final(have, &x);
+ if (!memcmp(have, want, 20))
+ printf("i=%d, deletion\n", i);
+#endif
+
+ /*
+ * replacement -- note that this tries each of the 256
+ * possible bytes. If you suspect a single-bit flip,
+ * it would be much shorter to just try the 8
+ * bit-flipped variants.
+ */
+ c = buf[i];
+ for (j = 0; j <= 0xff; j++) {
+ buf[i] = j;
+
+ memcpy(&x, &orig, sizeof(x));
+ SHA1_Update(&x, buf + i, len - i);
+ SHA1_Final(have, &x);
+ if (!memcmp(have, want, 20))
+ printf("i=%d, j=%02x\n", i, j);
+ }
+ buf[i] = c;
+
+#if 0
+ /* addition */
+ for (j = 0; j <= 0xff; j++) {
+ unsigned char extra = j;
+ memcpy(&x, &orig, sizeof(x));
+ SHA1_Update(&x, &extra, 1);
+ SHA1_Update(&x, buf + i, len - i);
+ SHA1_Final(have, &x);
+ if (!memcmp(have, want, 20))
+ printf("i=%d, addition=%02x", i, j);
+ }
+#endif
+
+ SHA1_Update(&orig, buf + i, 1);
+ counter++;
+ }
+
+ alarm(0);
+ fprintf(stderr, "\r%d\n", counter);
+ return 0;
+}
+--------------------------
diff --git a/Documentation/howto/revert-a-faulty-merge.txt b/Documentation/howto/revert-a-faulty-merge.txt
index 8a685483f4..19f59cc888 100644
--- a/Documentation/howto/revert-a-faulty-merge.txt
+++ b/Documentation/howto/revert-a-faulty-merge.txt
@@ -30,14 +30,14 @@ 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".
+IOW, `"diff W^..W"` is similar to `"diff -R M^..M"`.
Such a "revert" of a merge can be made with:
@@ -47,14 +47,14 @@ 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
+changes made in A or B will be in the result, because they were reverted
by W. That is what Alan saw.
Linus explains the situation:
@@ -81,7 +81,7 @@ 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
@@ -90,17 +90,17 @@ 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:
+changed) be equivalent to not having W or 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
@@ -111,25 +111,25 @@ 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,
+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
@@ -164,7 +164,7 @@ 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
+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.
diff --git a/Documentation/howto/revert-branch-rebase.txt b/Documentation/howto/revert-branch-rebase.txt
index a59ced8d04..a3e5595a56 100644
--- a/Documentation/howto/revert-branch-rebase.txt
+++ b/Documentation/howto/revert-branch-rebase.txt
@@ -12,10 +12,10 @@ How to revert an existing commit
================================
One of the changes I pulled into the 'master' branch turns out to
-break building GIT with GCC 2.95. While they were well intentioned
+break building Git with GCC 2.95. While they were well-intentioned
portability fixes, keeping things working with gcc-2.95 was also
important. Here is what I did to revert the change in the 'master'
-branch and to adjust the 'pu' branch, using core GIT tools and
+branch and to adjust the 'seen' branch, using core Git tools and
barebone Porcelain.
First, prepare a throw-away branch in case I screw things up.
@@ -104,11 +104,11 @@ $ git diff master..revert-c99
says nothing.
-Then we rebase the 'pu' branch as usual.
+Then we rebase the 'seen' branch as usual.
------------------------------------------------
-$ git checkout pu
-$ git tag pu-anchor pu
+$ git checkout seen
+$ git tag seen-anchor seen
$ git rebase master
* Applying: Redo "revert" using three-way merge machinery.
First trying simple merge strategy to cherry-pick.
@@ -127,20 +127,20 @@ First trying simple merge strategy to cherry-pick.
First trying simple merge strategy to cherry-pick.
------------------------------------------------
-The temporary tag 'pu-anchor' is me just being careful, in case 'git
+The temporary tag 'seen-anchor' is me just being careful, in case 'git
rebase' screws up. After this, I can do these for sanity check:
------------------------------------------------
-$ git diff pu-anchor..pu ;# make sure we got the master fix.
+$ git diff seen-anchor..seen ;# make sure we got the master fix.
$ make CC=gcc-2.95 clean test ;# make sure it fixed the breakage.
$ make clean test ;# make sure it did not cause other breakage.
------------------------------------------------
Everything is in the good order. I do not need the temporary branch
-nor tag anymore, so remove them:
+or tag anymore, so remove them:
------------------------------------------------
-$ rm -f .git/refs/tags/pu-anchor
+$ rm -f .git/refs/tags/seen-anchor
$ git branch -d revert-c99
------------------------------------------------
@@ -154,7 +154,7 @@ $ git pull . master
Packing 0 objects
Unpacking 0 objects
-* committish: e3a693c... refs/heads/master from .
+* commit-ish: e3a693c... refs/heads/master from .
Trying to merge e3a693c... into 8c1f5f0... using 10d781b...
Committed merge 7fb9b7262a1d1e0a47bbfdcbbcf50ce0635d3f8f
cache.h | 8 ++++----
@@ -168,18 +168,18 @@ Committed merge 7fb9b7262a1d1e0a47bbfdcbbcf50ce0635d3f8f
And the final repository status looks like this:
------------------------------------------------
-$ git show-branch --more=1 master pu rc
+$ git show-branch --more=1 master seen rc
! [master] Revert "Replace zero-length array decls with []."
- ! [pu] git-repack: Add option to repack all objects.
+ ! [seen] git-repack: Add option to repack all objects.
* [rc] Merge refs/heads/master from .
---
- + [pu] git-repack: Add option to repack all objects.
- + [pu~1] More documentation updates.
- + [pu~2] Show commits in topo order and name all commits.
- + [pu~3] mailinfo and applymbox updates
- + [pu~4] Document "git cherry-pick" and "git revert"
- + [pu~5] Remove git-apply-patch-script.
- + [pu~6] Redo "revert" using three-way merge machinery.
+ + [seen] git-repack: Add option to repack all objects.
+ + [seen~1] More documentation updates.
+ + [seen~2] Show commits in topo order and name all commits.
+ + [seen~3] mailinfo and applymbox updates
+ + [seen~4] Document "git cherry-pick" and "git revert"
+ + [seen~5] Remove git-apply-patch-script.
+ + [seen~6] Redo "revert" using three-way merge machinery.
- [rc] Merge refs/heads/master from .
++* [master] Revert "Replace zero-length array decls with []."
- [rc~1] Merge refs/heads/master from .
diff --git a/Documentation/howto/separating-topic-branches.txt b/Documentation/howto/separating-topic-branches.txt
index bd1027433b..81be0d6115 100644
--- a/Documentation/howto/separating-topic-branches.txt
+++ b/Documentation/howto/separating-topic-branches.txt
@@ -81,7 +81,7 @@ After I am done, I'd try a pretend-merge between "topicA" and
o---o---o---o---o---o
The last diff better not to show anything other than cleanups
-for crufts. Then I can finally clean things up:
+for cruft. Then I can finally clean things up:
$ git branch -D topic
$ git reset --hard HEAD^ ;# nuke pretend merge
diff --git a/Documentation/howto/setup-git-server-over-http.txt b/Documentation/howto/setup-git-server-over-http.txt
index a695f01f0e..bfe6f9b500 100644
--- a/Documentation/howto/setup-git-server-over-http.txt
+++ b/Documentation/howto/setup-git-server-over-http.txt
@@ -1,11 +1,15 @@
From: Rutger Nijlunsing <rutger@nospam.com>
-Subject: Setting up a git repository which can be pushed into and pulled from over HTTP(S).
+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
Content-type: text/asciidoc
-How to setup git server over http
+How to setup Git server over http
=================================
+NOTE: This document is from 2006. A lot has happened since then, and this
+document is now relevant mainly if your web host is not CGI capable.
+Almost everyone else should instead look at linkgit:git-http-backend[1].
+
Since Apache is one of those packages people like to compile
themselves while others prefer the bureaucrat's dream Debian, it is
impossible to give guidelines which will work for everyone. Just send
@@ -44,20 +48,20 @@ What's needed:
- have permissions to chown a directory
-- have git installed on the client, and
+- have Git installed on the client, and
-- either have git installed on the server or have a webdav client on
+- 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
+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
+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 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).
@@ -81,8 +85,8 @@ Initialize a bare repository
$ git --bare init
-Change the ownership to your web-server's credentials. Use "grep ^User
-httpd.conf" and "grep ^Group httpd.conf" to find out:
+Change the ownership to your web-server's credentials. Use `"grep ^User
+httpd.conf"` and `"grep ^Group httpd.conf"` to find out:
$ chown -R www.www .
@@ -177,7 +181,7 @@ On Debian:
Most tests should pass.
-A command line tool to test WebDAV is cadaver. If you prefer GUIs, for
+A command-line tool to test WebDAV is cadaver. If you prefer GUIs, for
example, konqueror can open WebDAV URLs as "webdav://..." or
"webdavs://...".
@@ -189,7 +193,7 @@ 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
+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.
@@ -240,8 +244,8 @@ 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
+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.
@@ -268,7 +272,7 @@ 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
+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.
diff --git a/Documentation/howto/update-hook-example.txt b/Documentation/howto/update-hook-example.txt
index a5193b1e5c..151ee84ceb 100644
--- a/Documentation/howto/update-hook-example.txt
+++ b/Documentation/howto/update-hook-example.txt
@@ -80,7 +80,7 @@ case "$1" in
info "The branch '$1' is new..."
else
# updating -- make sure it is a fast-forward
- mb=$(git-merge-base "$2" "$3")
+ mb=$(git merge-base "$2" "$3")
case "$mb,$2" in
"$2,$mb") info "Update is fast-forward" ;;
*) noff=y; info "This is not a fast-forward update.";;
@@ -179,7 +179,7 @@ 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/pu junio
+ +refs/heads/seen junio
refs/heads/cogito$ pasky
refs/heads/bw/.* linus
refs/heads/tmp/.* .*
@@ -187,6 +187,6 @@ whom. The format of each file would look like this:
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 and pu branches and make versioned tags. And anybody
-can do tmp/blah branches. The '+' sign at the pu record means
+do master and "seen" branches and make versioned tags. And anybody
+can do tmp/blah branches. The '+' sign at the "seen" 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 23cdf35435..7af2e52cf3 100644
--- a/Documentation/howto/use-git-daemon.txt
+++ b/Documentation/howto/use-git-daemon.txt
@@ -4,7 +4,7 @@ How to use git-daemon
=====================
Git can be run in inetd mode and in stand alone mode. But all you want is
-let a coworker pull from you, and therefore need to set up a git server
+let a coworker pull from you, and therefore need to set up a Git server
real quick, right?
Note that git-daemon is not really chatty at the moment, especially when
diff --git a/Documentation/howto/using-merge-subtree.txt b/Documentation/howto/using-merge-subtree.txt
index 1ae8d1214e..a499a94ac2 100644
--- a/Documentation/howto/using-merge-subtree.txt
+++ b/Documentation/howto/using-merge-subtree.txt
@@ -33,7 +33,7 @@ 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 merge -s ours --no-commit --allow-unrelated-histories Bproject/master <2>
$ git read-tree --prefix=dir-B/ -u Bproject/master <3>
$ git commit -m "Merge B project as our subdirectory" <4>
diff --git a/Documentation/howto/using-signed-tag-in-pull-request.txt b/Documentation/howto/using-signed-tag-in-pull-request.txt
index 00f693bde8..bbf040eda8 100644
--- a/Documentation/howto/using-signed-tag-in-pull-request.txt
+++ b/Documentation/howto/using-signed-tag-in-pull-request.txt
@@ -23,7 +23,7 @@ Earlier, a typical pull request may have started like this:
Froboz 3.2 (2011-09-30 14:20:57 -0700)
- are available in the git repository at:
+ are available in the Git repository at:
example.com:/git/froboz.git for-xyzzy
------------
@@ -107,7 +107,7 @@ The resulting msg.txt file begins like so:
Froboz 3.2 (2011-09-30 14:20:57 -0700)
- are available in the git repository at:
+ are available in the Git repository at:
example.com:/git/froboz.git tags/frotz-for-xyzzy