提交 8db9307c 编写于 作者: J Junio C Hamano

Documentaion updates.

Mostly making the formatted html prettier.
Signed-off-by: NJunio C Hamano <junkio@cox.net>
(cherry picked from 7adf1f15ebe074d4767df941817a6cf86d8e2533 commit)
上级 cc9f24d0
......@@ -2,10 +2,12 @@ MAN1_TXT=$(wildcard git-*.txt) gitk.txt
MAN7_TXT=git.txt
DOC_HTML=$(patsubst %.txt,%.html,$(MAN1_TXT) $(MAN7_TXT))
DOC_HTML += glossary.html
DOC_HTML += tutorial.html
DOC_HTML += howto-index.html
DOC_HTML += howto/revert-branch-rebase.html
ARTICLES = tutorial cvs-migration diffcore howto-index
# with their own formatting rules.
SP_ARTICLES = glossary howto/revert-branch-rebase
DOC_HTML += $(patsubst %,%.html,$(ARTICLES) $(SP_ARTICLES))
DOC_MAN1=$(patsubst %.txt,%.1,$(MAN1_TXT))
DOC_MAN7=$(patsubst %.txt,%.7,$(MAN7_TXT))
......@@ -58,21 +60,20 @@ clean:
%.xml : %.txt
asciidoc -b docbook -d manpage $<
git.html: git.txt ../README
glossary.html : glossary.txt sort_glossary.pl
cat $< | \
perl sort_glossary.pl | \
asciidoc -b xhtml11 - > glossary.html
tutorial.html : tutorial.txt
asciidoc -b xhtml11 tutorial.txt
howto-index.txt: howto-index.sh $(wildcard howto/*.txt)
rm -f $@+ $@
sh ./howto-index.sh $(wildcard howto/*.txt) >$@+
mv $@+ $@
howto-index.html: howto-index.txt
asciidoc -b xhtml11 howto-index.txt
$(patsubst %,%.html,$(ARTICLES)) : %.html : %.txt
asciidoc -b xhtml11 $*.txt
WEBDOC_DEST = /pub/software/scm/git/docs
......
Git for CVS users
=================
v0.99.5, Aug 2005
Ok, so you're a CVS user. That's ok, it's a treatable condition, and the
first step to recovery is admitting you have a problem. The fact that
......@@ -8,12 +9,12 @@ already.
The thing about CVS is that it absolutely sucks as a source control
manager, and you'll thus be happy with almost anything else. Git,
however, may be a bit _too_ different (read: "good") for your taste, and
however, may be a bit 'too' different (read: "good") for your taste, and
does a lot of things differently.
One particular suckage of CVS is very hard to work around: CVS is
basically a tool for tracking _file_ history, while git is a tool for
tracking _project_ history. This sometimes causes problems if you are
basically a tool for tracking 'file' history, while git is a tool for
tracking 'project' history. This sometimes causes problems if you are
used to doing very strange things in CVS, in particular if you're doing
things like making branches of just a subset of the project. Git can't
track that, since git never tracks things on the level of an individual
......@@ -22,17 +23,18 @@ file, only on the whole project level.
The good news is that most people don't do that, and in fact most sane
people think it's a bug in CVS that makes it tag (and check in changes)
one file at a time. So most projects you'll ever see will use CVS
_as_if_ it was sane. In which case you'll find it very easy indeed to
'as if' it was sane. In which case you'll find it very easy indeed to
move over to Git.
First off: this is not a git tutorial. See Documentation/tutorial.txt
for how git actually works. This is more of a random collection of
gotcha's and notes on converting from CVS to git.
First off: this is not a git tutorial. See
link:tutorial.html[Documentation/tutorial.txt] for how git
actually works. This is more of a random collection of gotcha's
and notes on converting from CVS to git.
Second: CVS has the notion of a "repository" as opposed to the thing
that you're actually working in (your working directory, or your
"checked out tree"). Git does not have that notion at all, and all git
working directories _are_ the repositories. However, you can easily
working directories 'are' the repositories. However, you can easily
emulate the CVS model by having one special "global repository", which
people can synchronize with. See details later, but in the meantime
just keep in mind that with git, every checked out working tree will
......@@ -55,7 +57,7 @@ will need the help of a program called "cvsps":
which is not actually related to git at all, but which makes CVS usage
look almost sane (ie you almost certainly want to have it even if you
decide to stay with CVS). However, git will want at _least_ version 2.1
decide to stay with CVS). However, git will want 'at least' version 2.1
of cvsps (available at the address above), and in fact will currently
refuse to work with anything else.
......
The output format from "git-diff-cache", "git-diff-tree" and
"git-diff-files" is very similar.
"git-diff-files" are very similar.
These commands all compare two sets of things; what are
compared are different:
......@@ -19,35 +19,41 @@ git-diff-files [<pattern>...]::
An output line is formatted this way:
------------------------------------------------
in-place edit :100644 100644 bcd1234... 0123456... M file0
copy-edit :100644 100644 abcd123... 1234567... C68 file1 file2
rename-edit :100644 100644 abcd123... 1234567... R86 file1 file3
create :000000 100644 0000000... 1234567... N file4
create :000000 100644 0000000... 1234567... A file4
delete :100644 000000 1234567... 0000000... D file5
unmerged :000000 000000 0000000... 0000000... U file6
------------------------------------------------
That is, from the left to the right:
(1) a colon.
(2) mode for "src"; 000000 if creation or unmerged.
(3) a space.
(4) mode for "dst"; 000000 if deletion or unmerged.
(5) a space.
(6) sha1 for "src"; 0{40} if creation or unmerged.
(7) a space.
(8) sha1 for "dst"; 0{40} if creation, unmerged or "look at work tree".
(9) a space.
(10) status, followed by optional "score" number.
(11) a tab or a NUL when '-z' option is used.
(12) path for "src"
(13) a tab or a NUL when '-z' option is used; only exists for C or R.
(14) path for "dst"; only exists for C or R.
(15) an LF or a NUL when '-z' option is used, to terminate the record.
. a colon.
. mode for "src"; 000000 if creation or unmerged.
. a space.
. mode for "dst"; 000000 if deletion or unmerged.
. a space.
. sha1 for "src"; 0\{40\} if creation or unmerged.
. a space.
. sha1 for "dst"; 0\{40\} if creation, unmerged or "look at work tree".
. a space.
. status, followed by optional "score" number.
. a tab or a NUL when '-z' option is used.
. path for "src"
. a tab or a NUL when '-z' option is used; only exists for C or R.
. path for "dst"; only exists for C or R.
. an LF or a NUL when '-z' option is used, to terminate the record.
<sha1> is shown as all 0's if new is a file on the filesystem
and it is out of sync with the cache. Example:
and it is out of sync with the cache.
:100644 100644 5be4a4...... 000000...... M file.c
Example:
------------------------------------------------
:100644 100644 5be4a4...... 000000...... M file.c
------------------------------------------------
Generating patches with -p
--------------------------
......@@ -107,20 +113,20 @@ Git specific extension to diff format
What -p option produces is slightly different from the
traditional diff format.
(1) It is preceeded with a "git diff" header, that looks like
1. It is preceeded with a "git diff" header, that looks like
this:
diff --git a/file1 b/file2
+
The `a/` and `b/` filenames are the same unless rename/copy is
involved. Especially, even for a creation or a deletion,
`/dev/null` is _not_ used in place of `a/` or `b/` filenames.
+
When rename/copy is involved, `file1` and `file2` shows the
name of the source file of the rename/copy and the name of
the file that rename/copy produces, respectively.
The a/ and b/ filenames are the same unless rename/copy is
involved. Especially, even for a creation or a deletion,
/dev/null is _not_ used in place of a/ or b/ filename.
When rename/copy is involved, file1 and file2 shows the
name of the source file of the rename/copy and the name of
the file that rename/copy produces, respectively.
(2) It is followed by extended header lines that are one or
2. It is followed by extended header lines that are one or
more of:
old mode <mode>
......
......@@ -51,3 +51,5 @@
Swap two inputs; that is, show differences from cache or
on-disk file to tree contents.
For more detailed explanation on these common options, see also
link:diffcore.html[diffcore documentation].
......@@ -22,8 +22,8 @@ The git-diff-* family works by first comparing two sets of
files:
- git-diff-cache compares contents of a "tree" object and the
working directory (when --cached flag is not used) or a
"tree" object and the index file (when --cached flag is
working directory (when '--cached' flag is not used) or a
"tree" object and the index file (when '--cached' flag is
used);
- git-diff-files compares contents of the index file and the
......@@ -37,29 +37,31 @@ comparison is passed from these commands to what is internally
called "diffcore", in a format similar to what is output when
the -p option is not used. E.g.
in-place edit :100644 100644 bcd1234... 0123456... M file0
create :000000 100644 0000000... 1234567... N file4
delete :100644 000000 1234567... 0000000... D file5
unmerged :000000 000000 0000000... 0000000... U file6
------------------------------------------------
in-place edit :100644 100644 bcd1234... 0123456... M file0
create :000000 100644 0000000... 1234567... A file4
delete :100644 000000 1234567... 0000000... D file5
unmerged :000000 000000 0000000... 0000000... U file6
------------------------------------------------
The diffcore mechanism is fed a list of such comparison results
(each of which is called "filepair", although at this point each
of them talks about a single file), and transforms such a list
into another list. There are currently 6 such transformations:
- diffcore-pathspec
- diffcore-break
- diffcore-rename
- diffcore-merge-broken
- diffcore-pickaxe
- diffcore-order
- diffcore-pathspec
- diffcore-break
- diffcore-rename
- diffcore-merge-broken
- diffcore-pickaxe
- diffcore-order
These are applied in sequence. The set of filepairs git-diff-*
These are applied in sequence. The set of filepairs git-diff-\*
commands find are used as the input to diffcore-pathspec, and
the output from diffcore-pathspec is used as the input to the
next transformation. The final result is then passed to the
output routine and generates either diff-raw format (see Output
format sections of the manual for git-diff-* commands) or
format sections of the manual for git-diff-\* commands) or
diff-patch format.
......@@ -87,13 +89,17 @@ used to detect a filepair that represents "complete rewrite" and
break such filepair into two filepairs that represent delete and
create. E.g. If the input contained this filepair:
:100644 100644 bcd1234... 0123456... M file0
------------------------------------------------
:100644 100644 bcd1234... 0123456... M file0
------------------------------------------------
and if it detects that the file "file0" is completely rewritten,
it changes it to:
:100644 000000 bcd1234... 0000000... D file0
:000000 100644 0000000... 0123456... N file0
------------------------------------------------
:100644 000000 bcd1234... 0000000... D file0
:000000 100644 0000000... 0123456... A file0
------------------------------------------------
For the purpose of breaking a filepair, diffcore-break examines
the extent of changes between the contents of the files before
......@@ -117,14 +123,18 @@ controlled by the -M option (to detect renames) and the -C option
(to detect copies as well) to the git-diff-* commands. If the
input contained these filepairs:
:100644 000000 0123456... 0000000... D fileX
:000000 100644 0000000... 0123456... N file0
------------------------------------------------
:100644 000000 0123456... 0000000... D fileX
:000000 100644 0000000... 0123456... A file0
------------------------------------------------
and the contents of the deleted file fileX is similar enough to
the contents of the created file file0, then rename detection
merges these filepairs and creates:
:100644 100644 0123456... 0123456... R100 fileX file0
------------------------------------------------
:100644 100644 0123456... 0123456... R100 fileX file0
------------------------------------------------
When the "-C" option is used, the original contents of modified
files and contents of unchanged files are considered as
......@@ -133,15 +143,19 @@ addition to the deleted files. If the input were like these
filepairs, that talk about a modified file fileY and a newly
created file file0:
:100644 100644 0123456... 1234567... M fileY
:000000 100644 0000000... 0123456... N file0
------------------------------------------------
:100644 100644 0123456... 1234567... M fileY
:000000 100644 0000000... 0123456... A file0
------------------------------------------------
the original contents of fileY and the resulting contents of
file0 are compared, and if they are similar enough, they are
changed to:
:100644 100644 0123456... 1234567... M fileY
:100644 100644 0123456... 0123456... C100 fileY file0
------------------------------------------------
:100644 100644 0123456... 1234567... M fileY
:100644 100644 0123456... 0123456... C100 fileY file0
------------------------------------------------
In both rename and copy detection, the same "extent of changes"
algorithm used in diffcore-break is used to determine if two
......@@ -151,11 +165,11 @@ number after "-M" or "-C" option (e.g. "-M8" to tell it to use
8/10 = 80%).
Note. When the "-C" option is used with --find-copies-harder
option, git-diff-* commands feed unmodified filepairs to
option, git-diff-\* commands feed unmodified filepairs to
diffcore mechanism as well as modified ones. This lets the copy
detector consider unmodified files as copy source candidates at
the expense of making it slower. Without --find-copies-harder,
git-diff-* commands can detect copies only if the file that was
git-diff-\* commands can detect copies only if the file that was
copied happened to have been modified in the same changeset.
......@@ -186,10 +200,10 @@ material is deleted, the broken pairs are merged back into a
single modification) by giving a second number to -B option,
like these:
-B50/60 (give 50% "break score" to diffcore-break, use
60% for diffcore-merge-broken).
-B/60 (the same as above, since diffcore-break defautls to
50%).
* -B50/60 (give 50% "break score" to diffcore-break, use 60%
for diffcore-merge-broken).
* -B/60 (the same as above, since diffcore-break defaults to 50%).
Note that earlier implementation left a broken pair as a separate
creation and deletion patches. This was unnecessary hack and
......@@ -237,12 +251,14 @@ in the file are output before ones that match a later line, and
filepairs that do not match any glob pattern are output last.
As an example, typical orderfile for the core GIT probably
should look like this:
would look like this:
------------------------------------------------
README
Makefile
Documentation
*.h
*.c
t
------------------------------------------------
......@@ -12,6 +12,8 @@ SYNOPSIS
'git bisect' bad <rev>
'git bisect' good <rev>
'git bisect' reset [<branch>]
'git bisect' visualize
DESCRIPTION
-----------
......@@ -67,6 +69,12 @@ branches ("git bisect start" will do that for you too, actually: it will
reset the bisection state, and before it does that it checks that you're
not using some old bisection branch).
During the bisection process, you can say
git bisect visualize
to see the currently remaining suspects in `gitk`.
Author
------
......
......@@ -19,11 +19,14 @@ This is reference information for the core git commands.
Before reading this cover to cover, you may want to take a look
at the link:tutorial.html[tutorial] document.
The Discussion section below contains much useful definition and
The <<Discussion>> section below contains much useful definition and
clarification info - read that first. And of the commands, I suggest
reading link:git-update-cache.html[git-update-cache] and
link:git-read-tree.html[git-read-tree] first - I wish I had!
If you are migrating from CVS, link:cvs-migration.html[cvs migration]
document may be helpful after you finish the tutorial.
After you get the general feel from the tutorial and this
overview page, you may want to take a look at the
link:howto-index.html[howto] documents.
......@@ -483,8 +486,8 @@ git Diffs
link:git-diff-files.html[git-diff-files];
link:git-diff-tree.html[git-diff-tree]
Discussion
----------
Discussion[[Discussion]]
------------------------
include::../README[]
Author
......
此差异已折叠。
......@@ -15,7 +15,7 @@
- "goddamn idiotic truckload of sh*t": when it breaks
This is a stupid (but extremely fast) directory content manager. It
doesn't do a whole lot, but what it _does_ do is track directory
doesn't do a whole lot, but what it 'does' do is track directory
contents efficiently.
There are two object abstractions: the "object database", and the
......@@ -66,9 +66,11 @@ Regardless of object type, all objects share the following
characteristics: they are all deflated with zlib, and have a header
that not only specifies their tag, but also provides size information
about the data in the object. It's worth noting that the SHA1 hash
that is used to name the object is the hash of the original data.
that is used to name the object is the hash of the original data
plus this header, so `sha1sum` 'file' does not match the object name
for 'file'.
(Historical note: in the dawn of the age of git the hash
was the sha1 of the _compressed_ object)
was the sha1 of the 'compressed' object.)
As a result, the general consistency of an object can always be tested
independently of the contents or the type of the object: all objects can
......@@ -79,7 +81,7 @@ size> + <byte\0> + <binary object data>.
The structured objects can further have their structure and
connectivity to other objects verified. This is generally done with
the "git-fsck-cache" program, which generates a full dependency graph
the `git-fsck-cache` program, which generates a full dependency graph
of all objects, and verifies their internal consistency (in addition
to just verifying their superficial consistency through the hash).
......@@ -89,7 +91,7 @@ Blob Object
~~~~~~~~~~~
A "blob" object is nothing but a binary blob of data, and doesn't
refer to anything else. There is no signature or any other
verification of the data, so while the object is consistent (it _is_
verification of the data, so while the object is consistent (it 'is'
indexed by its sha1 hash, so the data itself is certainly correct), it
has absolutely no other attributes. No name associations, no
permissions. It is purely a blob of data (i.e. normally "file
......@@ -125,7 +127,7 @@ trust that the tree is immutable and its contents never change.
So you can trust the contents of a tree to be valid, the same way you
can trust the contents of a blob, but you don't know where those
contents _came_ from.
contents 'came' from.
Side note on trees: since a "tree" object is a sorted list of
"filename+content", you can create a diff between two trees without
......@@ -142,7 +144,8 @@ noticing that the blob stayed the same. However, renames with data
changes need a smarter "diff" implementation.
A tree is created with link:git-write-tree.html[git-write-tree] and
its data can be accessed by link:git-ls-tree.html[git-ls-tree]
its data can be accessed by link:git-ls-tree.html[git-ls-tree].
Two trees can be compared with link:git-diff-tree.html[git-diff-tree].
Commit Object
~~~~~~~~~~~~~
......@@ -161,19 +164,19 @@ The parents do not have to actually have any relationship with the
result, for example.
Note on commits: unlike real SCM's, commits do not contain
rename information or file mode chane information. All of that is
rename information or file mode change information. All of that is
implicit in the trees involved (the result tree, and the result trees
of the parents), and describing that makes no sense in this idiotic
file manager.
A commit is created with link:git-commit-tree.html[git-commit-tree] and
its data can be accessed by link:git-cat-file.html[git-cat-file]
its data can be accessed by link:git-cat-file.html[git-cat-file].
Trust
~~~~~
An aside on the notion of "trust". Trust is really outside the scope
of "git", but it's worth noting a few things. First off, since
everything is hashed with SHA1, you _can_ trust that an object is
everything is hashed with SHA1, you 'can' trust that an object is
intact and has not been messed with by external sources. So the name
of an object uniquely identifies a known state - just not a state that
you may want to trust.
......@@ -185,7 +188,7 @@ of history, with full contents. You can't later fake any step of the
way once you have the name of a commit.
So to introduce some real trust in the system, the only thing you need
to do is to digitally sign just _one_ special note, which includes the
to do is to digitally sign just 'one' special note, which includes the
name of a top-level commit. Your digital signature shows others
that you trust that commit, and the immutability of the history of
commits tells others that they can trust the whole history.
......@@ -212,8 +215,10 @@ Note that despite the tag features, "git" itself only handles content
integrity; the trust framework (and signature provision and
verification) has to come from outside.
A tag is created with link:git-mktag.html[git-mktag] and
its data can be accessed by link:git-cat-file.html[git-cat-file]
A tag is created with link:git-mktag.html[git-mktag],
its data can be accessed by link:git-cat-file.html[git-cat-file],
and the signature can be verified by
link:git-verify-tag-script.html[git-verify-tag].
The "index" aka "Current Directory Cache"
......@@ -228,7 +233,7 @@ meaning, and can be partially updated at any time.
In particular, the index certainly does not need to be consistent with
the current directory contents (in fact, most operations will depend on
different ways to make the index _not_ be consistent with the directory
different ways to make the index 'not' be consistent with the directory
hierarchy), but it has three very important attributes:
'(a) it can re-generate the full state it caches (not just the
......@@ -259,7 +264,7 @@ developed. If you blow the directory cache away entirely, you generally
haven't lost any information as long as you have the name of the tree
that it described.
At the same time, the directory index is at the same time also the
At the same time, the index is at the same time also the
staging area for creating new trees, and creating a new tree always
involves a controlled modification of the index file. In particular,
the index file can have the representation of an intermediate tree that
......@@ -293,18 +298,18 @@ i.e. it will normally just update existing cache entries.
To tell git that yes, you really do realize that certain files no
longer exist in the archive, or that new files should be added, you
should use the "--remove" and "--add" flags respectively.
should use the `--remove` and `--add` flags respectively.
NOTE! A "--remove" flag does _not_ mean that subsequent filenames will
NOTE! A `--remove` flag does 'not' mean that subsequent filenames will
necessarily be removed: if the files still exist in your directory
structure, the index will be updated with their new status, not
removed. The only thing "--remove" means is that update-cache will be
removed. The only thing `--remove` means is that update-cache will be
considering a removed file to be a valid thing, and if the file really
does not exist any more, it will update the index accordingly.
As a special case, you can also do "git-update-cache --refresh", which
As a special case, you can also do `git-update-cache --refresh`, which
will refresh the "stat" information of each index to match the current
stat information. It will _not_ update the object status itself, and
stat information. It will 'not' update the object status itself, and
it will only update the fields that are used to quickly test whether
an object still matches its old backing store object.
......@@ -332,7 +337,7 @@ index. Normal operation is just
git-read-tree <sha1 of tree>
and your index file will now be equivalent to the tree that you saved
earlier. However, that is only your _index_ file: your working
earlier. However, that is only your 'index' file: your working
directory contents have not been modified.
4) index -> working directory
......@@ -342,20 +347,21 @@ You update your working directory from the index by "checking out"
files. This is not a very common operation, since normally you'd just
keep your files updated, and rather than write to your working
directory, you'd tell the index files about the changes in your
working directory (i.e. "git-update-cache").
working directory (i.e. `git-update-cache`).
However, if you decide to jump to a new version, or check out somebody
else's version, or just restore a previous tree, you'd populate your
index file with read-tree, and then you need to check out the result
with
git-checkout-cache filename
or, if you want to check out all of the index, use "-a".
or, if you want to check out all of the index, use `-a`.
NOTE! git-checkout-cache normally refuses to overwrite old files, so
if you have an old version of the tree already checked out, you will
need to use the "-f" flag (_before_ the "-a" flag or the filename) to
_force_ the checkout.
need to use the "-f" flag ('before' the "-a" flag or the filename) to
'force' the checkout.
Finally, there are a few odds and ends which are not purely moving
......@@ -388,9 +394,9 @@ redirection from a pipe or file, or by just typing it at the tty).
git-commit-tree will return the name of the object that represents
that commit, and you should save it away for later use. Normally,
you'd commit a new "HEAD" state, and while git doesn't care where you
you'd commit a new `HEAD` state, and while git doesn't care where you
save the note about that state, in practice we tend to just write the
result to the file ".git/HEAD", so that we can always see what the
result to the file `.git/HEAD`, so that we can always see what the
last committed state was.
6) Examining the data
......@@ -406,16 +412,16 @@ object:
shows the type of the object, and once you have the type (which is
usually implicit in where you find the object), you can use
git-cat-file blob|tree|commit <objectname>
git-cat-file blob|tree|commit|tag <objectname>
to show its contents. NOTE! Trees have binary content, and as a result
there is a special helper for showing that content, called
"git-ls-tree", which turns the binary content into a more easily
`git-ls-tree`, which turns the binary content into a more easily
readable form.
It's especially instructive to look at "commit" objects, since those
tend to be small and fairly self-explanatory. In particular, if you
follow the convention of having the top commit name in ".git/HEAD",
follow the convention of having the top commit name in `.git/HEAD`,
you can do
git-cat-file commit $(cat .git/HEAD)
......@@ -453,30 +459,88 @@ object.
Once you know the three trees you are going to merge (the one
"original" tree, aka the common case, and the two "result" trees, aka
the branches you want to merge), you do a "merge" read into the
index. This will throw away your old index contents, so you should
index. This will complain if it has to throw away your old index contents, so you should
make sure that you've committed those - in fact you would normally
always do a merge against your last commit (which should thus match
what you have in your current index anyway).
To do the merge, do
git-read-tree -m <origtree> <target1tree> <target2tree>
git-read-tree -m -u <origtree> <yourtree> <targettree>
which will do all trivial merge operations for you directly in the
index file, and you can just write the result out with
"git-write-tree".
`git-write-tree`.
Historical note. We did not have `-u` facility when this
section was first written, so we used to warn that
the merge is done in the index file, not in your
working directory, and your working directory will no longer match your
index.
NOTE! Because the merge is done in the index file, and not in your
working directory, your working directory will no longer match your
index. You can use "git-checkout-cache -f -a" to make the effect of
the merge be seen in your working directory.
NOTE2! Sadly, many merges aren't trivial. If there are files that have
8) Merging multiple trees, continued
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Sadly, many merges aren't trivial. If there are files that have
been added.moved or removed, or if both branches have modified the
same file, you will be left with an index tree that contains "merge
entries" in it. Such an index tree can _NOT_ be written out to a tree
entries" in it. Such an index tree can 'NOT' be written out to a tree
object, and you will have to resolve any such merge clashes using
other tools before you can write out the result.
[ fixme: talk about resolving merges here ]
You can examine such index state with `git-ls-files --unmerged`
command. An example:
------------------------------------------------
$ git-read-tree -m $orig HEAD $target
$ git-ls-files --unmerged
100644 263414f423d0e4d70dae8fe53fa34614ff3e2860 1 hello.c
100644 06fa6a24256dc7e560efa5687fa84b51f0263c3a 2 hello.c
100644 cc44c73eb783565da5831b4d820c962954019b69 3 hello.c
------------------------------------------------
Each line of the `git-ls-files --unmerged` output begins with
the blob mode bits, blob SHA1, 'stage number', and the
filename. The 'stage number' is git's way to say which tree it
came from: stage 1 corresponds to `$orig` tree, stage 2 `HEAD`
tree, and stage3 `$target` tree.
Earlier we said that trivial merges are done inside
`git-read-tree -m`. For example, if the file did not change
from `$orig` to `HEAD` nor `$target`, or if the file changed
from `$orig` to `HEAD` and `$orig` to `$target` the same way,
obviously the final outcome is what is in `HEAD`. What the
above example shows is that file `hello.c` was changed from
`$orig` to `HEAD` and `$orig` to `$target` in a different way.
You could resolve this by running your favorite 3-way merge
program, e.g. `diff3` or `merge`, on the blob objects from
these three stages yourself, like this:
------------------------------------------------
$ git-cat-file blob 263414f... >hello.c~1
$ git-cat-file blob 06fa6a2... >hello.c~2
$ git-cat-file blob cc44c73... >hello.c~3
$ merge hello.c~2 hello.c~1 hello.c~3
------------------------------------------------
This would leave the merge result in `hello.c~2` file, along
with conflict markers if there are conflicts. After verifying
the merge result makes sense, you can tell git what the final
merge result for this file is by:
mv -f hello.c~2 hello.c
git-update-cache hello.c
When a path is in unmerged state, running `git-update-cache` for
that path tells git to mark the path resolved.
The above is the description of a git merge at the lowest level,
to help you understand what conceptually happens under the hood.
In practice, nobody, not even git itself, uses three `git-cat-file`
for this. There is `git-merge-cache` program that extracts the
stages to temporary files and calls a `merge` script on it
git-merge-cache git-merge-one-file-script hello.c
and that is what higher level `git resolve` is implemented with.
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册