* jc/combined:
  combine-diff: a few more finishing touches.
  Documentation: clarify refname disambiguation rules.
  diff-format.txt: Combined diff format documentation supplement
  Remove --syslog in git-daemon inetd documentation examples.
  Documentation: updates to "Everyday GIT"
This commit is contained in:
Junio C Hamano 2006-10-26 01:18:55 -07:00
Родитель eb153837d8 d5f6a01af0
Коммит e893f7ad73
5 изменённых файлов: 148 добавлений и 54 удалений

Просмотреть файл

@ -156,31 +156,91 @@ to produce 'combined diff', which looks like this:
------------ ------------
diff --combined describe.c diff --combined describe.c
@@@ +98,7 @@@ index fabadb8,cc95eb0..4866510
return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1; --- a/describe.c
+++ b/describe.c
@@@ -98,20 -98,12 +98,20 @@@
return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1;
} }
- static void describe(char *arg) - static void describe(char *arg)
-static void describe(struct commit *cmit, int last_one) -static void describe(struct commit *cmit, int last_one)
++static void describe(char *arg, int last_one) ++static void describe(char *arg, int last_one)
{ {
+ unsigned char sha1[20]; + unsigned char sha1[20];
+ struct commit *cmit; + struct commit *cmit;
struct commit_list *list;
static int initialized = 0;
struct commit_name *n;
+ if (get_sha1(arg, sha1) < 0)
+ usage(describe_usage);
+ cmit = lookup_commit_reference(sha1);
+ if (!cmit)
+ usage(describe_usage);
+
if (!initialized) {
initialized = 1;
for_each_ref(get_name);
------------ ------------
1. It is preceded with a "git diff" header, that looks like
this (when '-c' option is used):
diff --combined file
+
or like this (when '--cc' option is used):
diff --c file
2. It is followed by one or more extended header lines
(this example shows a merge with two parents):
index <hash>,<hash>..<hash>
mode <mode>,<mode>..<mode>
new file mode <mode>
deleted file mode <mode>,<mode>
+
The `mode <mode>,<mode>..<mode>` line appears only if at least one of
the <mode> is diferent from the rest. Extended headers with
information about detected contents movement (renames and
copying detection) are designed to work with diff of two
<tree-ish> and are not used by combined diff format.
3. It is followed by two-line from-file/to-file header
--- a/file
+++ b/file
+
Similar to two-line header for traditional 'unified' diff
format, `/dev/null` is used to signal created or deleted
files.
4. Chunk header format is modified to prevent people from
accidentally feeding it to `patch -p1`. Combined diff format
was created for review of merge commit changes, and was not
meant for apply. The change is similar to the change in the
extended 'index' header:
@@@ <from-file-range> <from-file-range> <to-file-range> @@@
+
There are (number of parents + 1) `@` characters in the chunk
header for combined diff format.
Unlike the traditional 'unified' diff format, which shows two Unlike the traditional 'unified' diff format, which shows two
files A and B with a single column that has `-` (minus -- files A and B with a single column that has `-` (minus --
appears in A but removed in B), `+` (plus -- missing in A but appears in A but removed in B), `+` (plus -- missing in A but
added to B), or ` ` (space -- unchanged) prefix, this format added to B), or `" "` (space -- unchanged) prefix, this format
compares two or more files file1, file2,... with one file X, and compares two or more files file1, file2,... with one file X, and
shows how X differs from each of fileN. One column for each of shows how X differs from each of fileN. One column for each of
fileN is prepended to the output line to note how X's line is fileN is prepended to the output line to note how X's line is
different from it. different from it.
A `-` character in the column N means that the line appears in A `-` character in the column N means that the line appears in
fileN but it does not appear in the last file. A `+` character fileN but it does not appear in the result. A `+` character
in the column N means that the line appears in the last file, in the column N means that the line appears in the last file,
and fileN does not have that line. and fileN does not have that line (in other words, the line was
added, from the point of view of that parent).
In the above example output, the function signature was changed In the above example output, the function signature was changed
from both files (hence two `-` removals from both file1 and from both files (hence two `-` removals from both file1 and

Просмотреть файл

@ -1,22 +1,7 @@
Everyday GIT With 20 Commands Or So Everyday GIT With 20 Commands Or So
=================================== ===================================
GIT suite has over 100 commands, and the manual page for each of <<Basic Repository>> commands are needed by people who have a
them discusses what the command does and how it is used in
detail, but until you know what command should be used in order
to achieve what you want to do, you cannot tell which manual
page to look at, and if you know that already you do not need
the manual.
Does that mean you need to know all of them before you can use
git? Not at all. Depending on the role you play, the set of
commands you need to know is slightly different, but in any case
what you need to learn is far smaller than the full set of
commands to carry out your day-to-day work. This document is to
serve as a cheat-sheet and a set of pointers for people playing
various roles.
<<Basic Repository>> commands are needed by people who has a
repository --- that is everybody, because every working tree of repository --- that is everybody, because every working tree of
git is a repository. git is a repository.
@ -25,28 +10,27 @@ essential for anybody who makes a commit, even for somebody who
works alone. works alone.
If you work with other people, you will need commands listed in If you work with other people, you will need commands listed in
<<Individual Developer (Participant)>> section as well. the <<Individual Developer (Participant)>> section as well.
People who play <<Integrator>> role need to learn some more People who play the <<Integrator>> role need to learn some more
commands in addition to the above. commands in addition to the above.
<<Repository Administration>> commands are for system <<Repository Administration>> commands are for system
administrators who are responsible to care and feed git administrators who are responsible for the care and feeding
repositories to support developers. of git repositories.
Basic Repository[[Basic Repository]] Basic Repository[[Basic Repository]]
------------------------------------ ------------------------------------
Everybody uses these commands to feed and care git repositories. Everybody uses these commands to maintain git repositories.
* gitlink:git-init-db[1] or gitlink:git-clone[1] to create a * gitlink:git-init-db[1] or gitlink:git-clone[1] to create a
new repository. new repository.
* gitlink:git-fsck-objects[1] to validate the repository. * gitlink:git-fsck-objects[1] to check the repository for errors.
* gitlink:git-prune[1] to garbage collect cruft in the * gitlink:git-prune[1] to remove unused objects in the repository.
repository.
* gitlink:git-repack[1] to pack loose objects for efficiency. * gitlink:git-repack[1] to pack loose objects for efficiency.
@ -78,8 +62,8 @@ $ git repack -a -d <1>
$ git prune $ git prune
------------ ------------
+ +
<1> pack all the objects reachable from the refs into one pack <1> pack all the objects reachable from the refs into one pack,
and remove unneeded other packs then remove the other packs.
Individual Developer (Standalone)[[Individual Developer (Standalone)]] Individual Developer (Standalone)[[Individual Developer (Standalone)]]
@ -93,9 +77,6 @@ following commands.
* gitlink:git-log[1] to see what happened. * gitlink:git-log[1] to see what happened.
* gitlink:git-whatchanged[1] to find out where things have
come from.
* gitlink:git-checkout[1] and gitlink:git-branch[1] to switch * gitlink:git-checkout[1] and gitlink:git-branch[1] to switch
branches. branches.
@ -120,7 +101,7 @@ following commands.
Examples Examples
~~~~~~~~ ~~~~~~~~
Extract a tarball and create a working tree and a new repository to keep track of it.:: Use a tarball as a starting point for a new repository:
+ +
------------ ------------
$ tar zxf frotz.tar.gz $ tar zxf frotz.tar.gz
@ -203,7 +184,7 @@ $ cd my2.6
$ edit/compile/test; git commit -a -s <1> $ edit/compile/test; git commit -a -s <1>
$ git format-patch origin <2> $ git format-patch origin <2>
$ git pull <3> $ git pull <3>
$ git whatchanged -p ORIG_HEAD.. arch/i386 include/asm-i386 <4> $ git log -p ORIG_HEAD.. arch/i386 include/asm-i386 <4>
$ git pull git://git.kernel.org/pub/.../jgarzik/libata-dev.git ALL <5> $ git pull git://git.kernel.org/pub/.../jgarzik/libata-dev.git ALL <5>
$ git reset --hard ORIG_HEAD <6> $ git reset --hard ORIG_HEAD <6>
$ git prune <7> $ git prune <7>
@ -377,7 +358,7 @@ Run git-daemon to serve /pub/scm from inetd.::
------------ ------------
$ grep git /etc/inetd.conf $ grep git /etc/inetd.conf
git stream tcp nowait nobody \ git stream tcp nowait nobody \
/usr/bin/git-daemon git-daemon --inetd --syslog --export-all /pub/scm /usr/bin/git-daemon git-daemon --inetd --export-all /pub/scm
------------ ------------
+ +
The actual configuration line should be on one line. The actual configuration line should be on one line.
@ -397,7 +378,7 @@ service git
wait = no wait = no
user = nobody user = nobody
server = /usr/bin/git-daemon server = /usr/bin/git-daemon
server_args = --inetd --syslog --export-all --base-path=/pub/scm server_args = --inetd --export-all --base-path=/pub/scm
log_on_failure += USERID log_on_failure += USERID
} }
------------ ------------

Просмотреть файл

@ -165,8 +165,7 @@ git-daemon as inetd server::
+ +
------------------------------------------------ ------------------------------------------------
git stream tcp nowait nobody /usr/bin/git-daemon git stream tcp nowait nobody /usr/bin/git-daemon
git-daemon --inetd --verbose git-daemon --inetd --verbose --export-all
--syslog --export-all
/pub/foo /pub/bar /pub/foo /pub/bar
------------------------------------------------ ------------------------------------------------
@ -179,8 +178,7 @@ git-daemon as inetd server for virtual hosts::
+ +
------------------------------------------------ ------------------------------------------------
git stream tcp nowait nobody /usr/bin/git-daemon git stream tcp nowait nobody /usr/bin/git-daemon
git-daemon --inetd --verbose git-daemon --inetd --verbose --export-all
--syslog --export-all
--interpolated-path=/pub/%H%D --interpolated-path=/pub/%H%D
/pub/www.example.org/software /pub/www.example.org/software
/pub/www.example.com/software /pub/www.example.com/software

Просмотреть файл

@ -122,14 +122,30 @@ blobs contained in a commit.
your repository whose object name starts with dae86e. your repository whose object name starts with dae86e.
* An output from `git-describe`; i.e. a closest tag, followed by a * An output from `git-describe`; i.e. a closest tag, followed by a
dash, a 'g', and an abbreviated object name. dash, a `g`, and an abbreviated object name.
* A symbolic ref name. E.g. 'master' typically means the commit * A symbolic ref name. E.g. 'master' typically means the commit
object referenced by $GIT_DIR/refs/heads/master. If you object referenced by $GIT_DIR/refs/heads/master. If you
happen to have both heads/master and tags/master, you can happen to have both heads/master and tags/master, you can
explicitly say 'heads/master' to tell git which one you mean. explicitly say 'heads/master' to tell git which one you mean.
When ambiguous, a `<name>` is disambiguated by taking the
first match in the following rules:
* A suffix '@' followed by a date specification enclosed in a brace . if `$GIT_DIR/<name>` exists, that is what you mean (this is usually
useful only for `HEAD`, `FETCH_HEAD` and `MERGE_HEAD`);
. otherwise, `$GIT_DIR/refs/<name>` if exists;
. otherwise, `$GIT_DIR/refs/tags/<name>` if exists;
. otherwise, `$GIT_DIR/refs/heads/<name>` if exists;
. otherwise, `$GIT_DIR/refs/remotes/<name>` if exists;
. otherwise, `$GIT_DIR/refs/remotes/<name>/HEAD` if exists.
* A ref followed by the suffix '@' with a date specification
enclosed in a brace
pair (e.g. '\{yesterday\}', '\{1 month 2 weeks 3 days 1 hour 1 pair (e.g. '\{yesterday\}', '\{1 month 2 weeks 3 days 1 hour 1
second ago\}' or '\{1979-02-26 18:30:00\}') to specify the value second ago\}' or '\{1979-02-26 18:30:00\}') to specify the value
of the ref at a prior point in time. This suffix may only be of the ref at a prior point in time. This suffix may only be
@ -146,8 +162,9 @@ blobs contained in a commit.
* A suffix '{tilde}<n>' to a revision parameter means the commit * A suffix '{tilde}<n>' to a revision parameter means the commit
object that is the <n>th generation grand-parent of the named object that is the <n>th generation grand-parent of the named
commit object, following only the first parent. I.e. rev~3 is commit object, following only the first parent. I.e. rev~3 is
equivalent to rev{caret}{caret}{caret} which is equivalent to\ equivalent to rev{caret}{caret}{caret} which is equivalent to
rev{caret}1{caret}1{caret}1. rev{caret}1{caret}1{caret}1. See below for a illustration of
the usage of this form.
* A suffix '{caret}' followed by an object type name enclosed in * A suffix '{caret}' followed by an object type name enclosed in
brace pair (e.g. `v0.99.8{caret}\{commit\}`) means the object brace pair (e.g. `v0.99.8{caret}\{commit\}`) means the object

Просмотреть файл

@ -489,6 +489,12 @@ static void show_parent_lno(struct sline *sline, unsigned long l0, unsigned long
printf(" -%lu,%lu", l0, l1-l0); printf(" -%lu,%lu", l0, l1-l0);
} }
static int hunk_comment_line(const char *bol)
{
int ch = *bol & 0xff;
return (isalpha(ch) || ch == '_' || ch == '$');
}
static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent, static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent,
int use_color) int use_color)
{ {
@ -508,8 +514,13 @@ static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent,
struct sline *sl = &sline[lno]; struct sline *sl = &sline[lno];
unsigned long hunk_end; unsigned long hunk_end;
unsigned long rlines; unsigned long rlines;
while (lno <= cnt && !(sline[lno].flag & mark)) const char *hunk_comment = NULL;
while (lno <= cnt && !(sline[lno].flag & mark)) {
if (hunk_comment_line(sline[lno].bol))
hunk_comment = sline[lno].bol;
lno++; lno++;
}
if (cnt < lno) if (cnt < lno)
break; break;
else { else {
@ -526,6 +537,22 @@ static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent,
show_parent_lno(sline, lno, hunk_end, i); show_parent_lno(sline, lno, hunk_end, i);
printf(" +%lu,%lu ", lno+1, rlines); printf(" +%lu,%lu ", lno+1, rlines);
for (i = 0; i <= num_parent; i++) putchar(combine_marker); for (i = 0; i <= num_parent; i++) putchar(combine_marker);
if (hunk_comment) {
int comment_end = 0;
for (i = 0; i < 40; i++) {
int ch = hunk_comment[i] & 0xff;
if (!ch || ch == '\n')
break;
if (!isspace(ch))
comment_end = i;
}
if (comment_end)
putchar(' ');
for (i = 0; i < comment_end; i++)
putchar(hunk_comment[i]);
}
printf("%s\n", c_reset); printf("%s\n", c_reset);
while (lno < hunk_end) { while (lno < hunk_end) {
struct lline *ll; struct lline *ll;
@ -707,6 +734,8 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
int use_color = opt->color_diff; int use_color = opt->color_diff;
const char *c_meta = diff_get_color(use_color, DIFF_METAINFO); const char *c_meta = diff_get_color(use_color, DIFF_METAINFO);
const char *c_reset = diff_get_color(use_color, DIFF_RESET); const char *c_reset = diff_get_color(use_color, DIFF_RESET);
int added = 0;
int deleted = 0;
if (rev->loginfo) if (rev->loginfo)
show_log(rev, opt->msg_sep); show_log(rev, opt->msg_sep);
@ -722,7 +751,10 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
printf("..%s%s\n", abb, c_reset); printf("..%s%s\n", abb, c_reset);
if (mode_differs) { if (mode_differs) {
int added = !!elem->mode; deleted = !elem->mode;
/* We say it was added if nobody had it */
added = !deleted;
for (i = 0; added && i < num_parent; i++) for (i = 0; added && i < num_parent; i++)
if (elem->parent[i].status != if (elem->parent[i].status !=
DIFF_STATUS_ADDED) DIFF_STATUS_ADDED)
@ -731,7 +763,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
printf("%snew file mode %06o", printf("%snew file mode %06o",
c_meta, elem->mode); c_meta, elem->mode);
else { else {
if (!elem->mode) if (deleted)
printf("%sdeleted file ", c_meta); printf("%sdeleted file ", c_meta);
printf("mode "); printf("mode ");
for (i = 0; i < num_parent; i++) { for (i = 0; i < num_parent; i++) {
@ -743,8 +775,14 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
} }
printf("%s\n", c_reset); printf("%s\n", c_reset);
} }
dump_quoted_path("--- a/", elem->path, c_meta, c_reset); if (added)
dump_quoted_path("+++ b/", elem->path, c_meta, c_reset); dump_quoted_path("--- /dev/", "null", c_meta, c_reset);
else
dump_quoted_path("--- a/", elem->path, c_meta, c_reset);
if (deleted)
dump_quoted_path("+++ /dev/", "null", c_meta, c_reset);
else
dump_quoted_path("+++ b/", elem->path, c_meta, c_reset);
dump_sline(sline, cnt, num_parent, opt->color_diff); dump_sline(sline, cnt, num_parent, opt->color_diff);
} }
free(result); free(result);