summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Documentation/config.txt4
-rw-r--r--Documentation/diff-options.txt5
-rw-r--r--Documentation/git-blame.txt39
-rw-r--r--Documentation/git-for-each-ref.txt181
-rw-r--r--Documentation/git-grep.txt11
-rw-r--r--Documentation/git-pack-objects.txt13
-rw-r--r--Documentation/git-rebase.txt5
-rw-r--r--Documentation/git-repack.txt14
-rw-r--r--Makefile8
-rw-r--r--archive-zip.c17
-rw-r--r--blame.c453
-rw-r--r--builtin-annotate.c25
-rw-r--r--builtin-apply.c4
-rw-r--r--builtin-for-each-ref.c874
-rw-r--r--builtin-grep.c4
-rw-r--r--builtin-pack-objects.c252
-rw-r--r--builtin-unpack-objects.c140
-rw-r--r--builtin.h4
-rw-r--r--cache.h5
-rw-r--r--combine-diff.c9
-rw-r--r--contrib/emacs/vc-git.el2
-rw-r--r--diff.c30
-rw-r--r--diff.h16
-rw-r--r--fetch-pack.c5
-rwxr-xr-xgit-annotate.perl708
-rwxr-xr-xgit-bisect.sh11
-rwxr-xr-xgit-clone.sh61
-rwxr-xr-xgit-cvsimport.perl25
-rwxr-xr-xgit-cvsserver.perl14
-rwxr-xr-xgit-fetch.sh41
-rwxr-xr-xgit-merge.sh2
-rwxr-xr-xgit-rebase.sh14
-rwxr-xr-xgit-repack.sh11
-rwxr-xr-xgit-resolve.sh2
-rwxr-xr-xgit-send-email.perl35
-rwxr-xr-xgit-svnimport.perl93
-rw-r--r--git.c2
-rw-r--r--gitweb/README16
-rw-r--r--gitweb/gitweb.css2
-rwxr-xr-xgitweb/gitweb.perl423
-rw-r--r--grep.c114
-rw-r--r--grep.h2
-rw-r--r--index-pack.c331
-rw-r--r--object.c68
-rw-r--r--object.h6
-rw-r--r--pack.h3
-rw-r--r--quote.c38
-rw-r--r--quote.h4
-rw-r--r--revision.c9
-rw-r--r--sha1_file.c113
-rw-r--r--t/t4013/diff.diff-tree_--pretty_--root_--summary_initial2
-rwxr-xr-xt/t5000-tar-tree.sh35
-rw-r--r--upload-pack.c10
-rw-r--r--wt-status.c14
55 files changed, 2870 insertions, 1460 deletions
diff --git a/.gitignore b/.gitignore
index 25eb4637a6..b670877510 100644
--- a/.gitignore
+++ b/.gitignore
@@ -37,6 +37,7 @@ git-fetch
git-fetch-pack
git-findtags
git-fmt-merge-msg
+git-for-each-ref
git-format-patch
git-fsck-objects
git-get-tar-commit-id
diff --git a/Documentation/config.txt b/Documentation/config.txt
index ee51fe3b9f..026d4cf9ad 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -242,6 +242,10 @@ remote.<name>.push::
The default set of "refspec" for gitlink:git-push[1]. See
gitlink:git-push[1].
+repack.usedeltabaseoffset::
+ Allow gitlink:git-repack[1] to create packs that uses
+ delta-base offset. Defaults to false.
+
show.difftree::
The default gitlink:git-diff-tree[1] arguments to be used
for gitlink:git-show[1].
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index 7b7b9e8ce9..e112172ca5 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -16,6 +16,11 @@
The width of the filename part can be controlled by
giving another width to it separated by a comma.
+--numstat::
+ Similar to \--stat, but shows number of added and
+ deleted lines in decimal notation and pathname without
+ abbreviation, to make it more machine friendly.
+
--summary::
Output a condensed summary of extended header information
such as creations, renames and mode changes.
diff --git a/Documentation/git-blame.txt b/Documentation/git-blame.txt
index e1f89444a9..9891c1d377 100644
--- a/Documentation/git-blame.txt
+++ b/Documentation/git-blame.txt
@@ -7,7 +7,7 @@ git-blame - Show what revision and author last modified each line of a file
SYNOPSIS
--------
-'git-blame' [-c] [-l] [-t] [-S <revs-file>] [--] <file> [<rev>]
+'git-blame' [-c] [-l] [-t] [-f] [-n] [-p] [-S <revs-file>] [--] <file> [<rev>]
DESCRIPTION
-----------
@@ -45,10 +45,47 @@ OPTIONS
-S, --rev-file <revs-file>::
Use revs from revs-file instead of calling gitlink:git-rev-list[1].
+-f, --show-name::
+ Show filename in the original commit. By default
+ filename is shown if there is any line that came from a
+ file with different name, due to rename detection.
+
+-n, --show-number::
+ Show line number in the original commit (Default: off).
+
+-p, --porcelain::
+ Show in a format designed for machine consumption.
+
-h, --help::
Show help message.
+THE PORCELAIN FORMAT
+--------------------
+
+In this format, each line is output after a header; the
+header at the minumum has the first line which has:
+
+- 40-byte SHA-1 of the commit the line is attributed to;
+- the line number of the line in the original file;
+- the line number of the line in the final file;
+- on a line that starts a group of line from a different
+ commit than the previous one, the number of lines in this
+ group. On subsequent lines this field is absent.
+
+This header line is followed by the following information
+at least once for each commit:
+
+- author name ("author"), email ("author-mail"), time
+ ("author-time"), and timezone ("author-tz"); similarly
+ for committer.
+- filename in the commit the line is attributed to.
+- the first line of the commit log message ("summary").
+
+The contents of the actual line is output after the above
+header, prefixed by a TAB. This is to allow adding more
+header elements later.
+
SEE ALSO
--------
gitlink:git-annotate[1]
diff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt
new file mode 100644
index 0000000000..d5fdcef8d9
--- /dev/null
+++ b/Documentation/git-for-each-ref.txt
@@ -0,0 +1,181 @@
+git-for-each-ref(1)
+===================
+
+NAME
+----
+git-for-each-ref - Output information on each ref
+
+SYNOPSIS
+--------
+'git-for-each-ref' [--count=<count>]* [--shell|--perl|--python] [--sort=<key>]* [--format=<format>] [<pattern>]
+
+DESCRIPTION
+-----------
+
+Iterate over all refs that match `<pattern>` and show them
+according to the given `<format>`, after sorting them according
+to the given set of `<key>`s. If `<max>` is given, stop after
+showing that many refs. The interporated values in `<format>`
+can optionally be quoted as string literals in the specified
+host language allowing their direct evaluation in that language.
+
+OPTIONS
+-------
+<count>::
+ By default the command shows all refs that match
+ `<pattern>`. This option makes it stop after showing
+ that many refs.
+
+<key>::
+ A field name to sort on. Prefix `-` to sort in
+ descending order of the value. When unspecified,
+ `refname` is used. More than one sort keys can be
+ given.
+
+<format>::
+ A string that interpolates `%(fieldname)` from the
+ object pointed at by a ref being shown. If `fieldname`
+ is prefixed with an asterisk (`*`) and the ref points
+ at a tag object, the value for the field in the object
+ tag refers is used. When unspecified, defaults to
+ `%(refname)`.
+
+<pattern>::
+ If given, the name of the ref is matched against this
+ using fnmatch(3). Refs that do not match the pattern
+ are not shown.
+
+--shell, --perl, --python::
+ If given, strings that substitute `%(fieldname)`
+ placeholders are quoted as string literals suitable for
+ the specified host language. This is meant to produce
+ a scriptlet that can directly be `eval`ed.
+
+
+FIELD NAMES
+-----------
+
+Various values from structured fields in referenced objects can
+be used to interpolate into the resulting output, or as sort
+keys.
+
+For all objects, the following names can be used:
+
+refname::
+ The name of the ref (the part after $GIT_DIR/refs/).
+
+objecttype::
+ The type of the object (`blob`, `tree`, `commit`, `tag`).
+
+objectsize::
+ The size of the object (the same as `git-cat-file -s` reports).
+
+objectname::
+ The object name (aka SHA-1).
+
+In addition to the above, for commit and tag objects, the header
+field names (`tree`, `parent`, `object`, `type`, and `tag`) can
+be used to specify the value in the header field.
+
+Fields that have name-email-date tuple as its value (`author`,
+`committer`, and `tagger`) can be suffixed with `name`, `email`,
+and `date` to extract the named component.
+
+The first line of the message in a commit and tag object is
+`subject`, the remaining lines are `body`. The whole message
+is `contents`.
+
+For sorting purposes, fields with numeric values sort in numeric
+order (`objectsize`, `authordate`, `committerdate`, `taggerdate`).
+All other fields are used to sort in their byte-value order.
+
+In any case, a field name that refers to a field inapplicable to
+the object referred by the ref does not cause an error. It
+returns an empty string instead.
+
+
+EXAMPLES
+--------
+
+An example directly producing formatted text. Show the most recent
+3 tagged commits::
+
+------------
+#!/bin/sh
+
+git-for-each-ref --count=3 --sort='-*authordate' \
+--format='From: %(*authorname) %(*authoremail)
+Subject: %(*subject)
+Date: %(*authordate)
+Ref: %(*refname)
+
+%(*body)
+' 'refs/tags'
+------------
+
+
+A simple example showing the use of shell eval on the output,
+demonstrating the use of --shell. List the prefixes of all heads::
+------------
+#!/bin/sh
+
+git-for-each-ref --shell --format="ref=%(refname)" refs/heads | \
+while read entry
+do
+ eval "$entry"
+ echo `dirname $ref`
+done
+------------
+
+
+A bit more elaborate report on tags, demonstrating that the format
+may be an entire script::
+------------
+#!/bin/sh
+
+fmt='
+ r=%(refname)
+ t=%(*objecttype)
+ T=${r#refs/tags/}
+
+ o=%(*objectname)
+ n=%(*authorname)
+ e=%(*authoremail)
+ s=%(*subject)
+ d=%(*authordate)
+ b=%(*body)
+
+ kind=Tag
+ if test "z$t" = z
+ then
+ # could be a lightweight tag
+ t=%(objecttype)
+ kind="Lightweight tag"
+ o=%(objectname)
+ n=%(authorname)
+ e=%(authoremail)
+ s=%(subject)
+ d=%(authordate)
+ b=%(body)
+ fi
+ echo "$kind $T points at a $t object $o"
+ if test "z$t" = zcommit
+ then
+ echo "The commit was authored by $n $e
+at $d, and titled
+
+ $s
+
+Its message reads as:
+"
+ echo "$b" | sed -e "s/^/ /"
+ echo
+ fi
+'
+
+eval=`git-for-each-ref --shell --format="$fmt" \
+ --sort='*objecttype' \
+ --sort=-taggerdate \
+ refs/tags`
+eval "$eval"
+------------
diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt
index d8af4d961b..bfbece9864 100644
--- a/Documentation/git-grep.txt
+++ b/Documentation/git-grep.txt
@@ -14,7 +14,7 @@ SYNOPSIS
[-v | --invert-match] [-h|-H] [--full-name]
[-E | --extended-regexp] [-G | --basic-regexp] [-F | --fixed-strings]
[-n] [-l | --files-with-matches] [-L | --files-without-match]
- [-c | --count]
+ [-c | --count] [--all-match]
[-A <post-context>] [-B <pre-context>] [-C <context>]
[-f <file>] [-e] <pattern> [--and|--or|--not|(|)|-e <pattern>...]
[<tree>...]
@@ -96,6 +96,11 @@ OPTIONS
higher precedence than `--or`. `-e` has to be used for all
patterns.
+--all-match::
+ When giving multiple pattern expressions combined with `--or`,
+ this flag is specified to limit the match to files that
+ have lines to match all of them.
+
`<tree>...`::
Search blobs in the trees for specified patterns.
@@ -111,6 +116,10 @@ git grep -e \'#define\' --and \( -e MAX_PATH -e PATH_MAX \)::
Looks for a line that has `#define` and either `MAX_PATH` or
`PATH_MAX`.
+git grep --all-match -e NODE -e Unexpected::
+ Looks for a line that has `NODE` or `Unexpected` in
+ files that have lines that match both.
+
Author
------
Originally written by Linus Torvalds <torvalds@osdl.org>, later
diff --git a/Documentation/git-pack-objects.txt b/Documentation/git-pack-objects.txt
index f52e8fa8bf..a1e55054bd 100644
--- a/Documentation/git-pack-objects.txt
+++ b/Documentation/git-pack-objects.txt
@@ -9,7 +9,7 @@ git-pack-objects - Create a packed archive of objects
SYNOPSIS
--------
[verse]
-'git-pack-objects' [-q] [--no-reuse-delta] [--non-empty]
+'git-pack-objects' [-q] [--no-reuse-delta] [--delta-base-offset] [--non-empty]
[--local] [--incremental] [--window=N] [--depth=N]
[--revs [--unpacked | --all]*] [--stdout | base-name] < object-list
@@ -111,6 +111,17 @@ base-name::
This flag tells the command not to reuse existing deltas
but compute them from scratch.
+--delta-base-offset::
+ A packed archive can express base object of a delta as
+ either 20-byte object name or as an offset in the
+ stream, but older version of git does not understand the
+ latter. By default, git-pack-objects only uses the
+ former format for better compatibility. This option
+ allows the command to use the latter format for
+ compactness. Depending on the average delta chain
+ length, this option typically shrinks the resulting
+ packfile by 3-5 per-cent.
+
Author
------
diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 9d7bcaa38c..10f2924f4d 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -7,7 +7,7 @@ git-rebase - Rebase local commits to a new head
SYNOPSIS
--------
-'git-rebase' [--merge] [--onto <newbase>] <upstream> [<branch>]
+'git-rebase' [-v] [--merge] [--onto <newbase>] <upstream> [<branch>]
'git-rebase' --continue | --skip | --abort
@@ -121,6 +121,9 @@ OPTIONS
is used instead (`git-merge-recursive` when merging a single
head, `git-merge-octopus` otherwise). This implies --merge.
+-v, \--verbose::
+ Display a diffstat of what changed upstream since the last rebase.
+
include::merge-strategies.txt[]
NOTES
diff --git a/Documentation/git-repack.txt b/Documentation/git-repack.txt
index d2eaa0995d..0fa47e3b01 100644
--- a/Documentation/git-repack.txt
+++ b/Documentation/git-repack.txt
@@ -67,6 +67,20 @@ OPTIONS
The default value for both --window and --depth is 10.
+Configuration
+-------------
+
+When configuration variable `repack.UseDeltaBaseOffset` is set
+for the repository, the command passes `--delta-base-offset`
+option to `git-pack-objects`; this typically results in slightly
+smaller packs, but the generated packs are incompatible with
+versions of git older than (and including) v1.4.3; do not set
+the variable in a repository that older version of git needs to
+be able to read (this includes repositories from which packs can
+be copied out over http or rsync, and people who obtained packs
+that way can try to use older git with it).
+
+
Author
------
Written by Linus Torvalds <torvalds@osdl.org>
diff --git a/Makefile b/Makefile
index 66c8b4b127..2d62efb5c4 100644
--- a/Makefile
+++ b/Makefile
@@ -132,6 +132,8 @@ GITWEB_HOMETEXT = indextext.html
GITWEB_CSS = gitweb.css
GITWEB_LOGO = git-logo.png
GITWEB_FAVICON = git-favicon.png
+GITWEB_SITE_HEADER =
+GITWEB_SITE_FOOTER =
export prefix bindir gitexecdir template_dir GIT_PYTHON_DIR
@@ -173,7 +175,7 @@ SCRIPT_SH = \
SCRIPT_PERL = \
git-archimport.perl git-cvsimport.perl git-relink.perl \
git-shortlog.perl git-rerere.perl \
- git-annotate.perl git-cvsserver.perl \
+ git-cvsserver.perl \
git-svnimport.perl git-cvsexportcommit.perl \
git-send-email.perl git-svn.perl
@@ -265,6 +267,7 @@ LIB_OBJS = \
BUILTIN_OBJS = \
builtin-add.o \
+ builtin-annotate.o \
builtin-apply.o \
builtin-archive.o \
builtin-cat-file.o \
@@ -278,6 +281,7 @@ BUILTIN_OBJS = \
builtin-diff-stages.o \
builtin-diff-tree.o \
builtin-fmt-merge-msg.o \
+ builtin-for-each-ref.o \
builtin-grep.o \
builtin-init-db.o \
builtin-log.o \
@@ -675,6 +679,8 @@ gitweb/gitweb.cgi: gitweb/gitweb.perl
-e 's|++GITWEB_CSS++|$(GITWEB_CSS)|g' \
-e 's|++GITWEB_LOGO++|$(GITWEB_LOGO)|g' \
-e 's|++GITWEB_FAVICON++|$(GITWEB_FAVICON)|g' \
+ -e 's|++GITWEB_SITE_HEADER++|$(GITWEB_SITE_HEADER)|g' \
+ -e 's|++GITWEB_SITE_FOOTER++|$(GITWEB_SITE_FOOTER)|g' \
$< >$@+
chmod +x $@+
mv $@+ $@
diff --git a/archive-zip.c b/archive-zip.c
index 3ffdad68d1..28e7352e98 100644
--- a/archive-zip.c
+++ b/archive-zip.c
@@ -145,6 +145,7 @@ static int write_zip_entry(const unsigned char *sha1,
{
struct zip_local_header header;
struct zip_dir_header dirent;
+ unsigned long attr2;
unsigned long compressed_size;
unsigned long uncompressed_size;
unsigned long crc;
@@ -172,12 +173,16 @@ static int write_zip_entry(const unsigned char *sha1,
if (S_ISDIR(mode)) {
method = 0;
+ attr2 = 16;
result = READ_TREE_RECURSIVE;
out = NULL;
uncompressed_size = 0;
compressed_size = 0;
- } else if (S_ISREG(mode)) {
- method = zlib_compression_level == 0 ? 0 : 8;
+ } else if (S_ISREG(mode) || S_ISLNK(mode)) {
+ method = 0;
+ attr2 = S_ISLNK(mode) ? ((mode | 0777) << 16) : 0;
+ if (S_ISREG(mode) && zlib_compression_level != 0)
+ method = 8;
result = 0;
buffer = read_sha1_file(sha1, type, &size);
if (!buffer)
@@ -213,8 +218,8 @@ static int write_zip_entry(const unsigned char *sha1,
}
copy_le32(dirent.magic, 0x02014b50);
- copy_le16(dirent.creator_version, 0);
- copy_le16(dirent.version, 20);
+ copy_le16(dirent.creator_version, S_ISLNK(mode) ? 0x0317 : 0);
+ copy_le16(dirent.version, 10);
copy_le16(dirent.flags, 0);
copy_le16(dirent.compression_method, method);
copy_le16(dirent.mtime, zip_time);
@@ -227,7 +232,7 @@ static int write_zip_entry(const unsigned char *sha1,
copy_le16(dirent.comment_length, 0);
copy_le16(dirent.disk, 0);
copy_le16(dirent.attr1, 0);
- copy_le32(dirent.attr2, 0);
+ copy_le32(dirent.attr2, attr2);
copy_le32(dirent.offset, zip_offset);
memcpy(zip_dir + zip_dir_offset, &dirent, sizeof(struct zip_dir_header));
zip_dir_offset += sizeof(struct zip_dir_header);
@@ -236,7 +241,7 @@ static int write_zip_entry(const unsigned char *sha1,
zip_dir_entries++;
copy_le32(header.magic, 0x04034b50);
- copy_le16(header.version, 20);
+ copy_le16(header.version, 10);
copy_le16(header.flags, 0);
copy_le16(header.compression_method, method);
copy_le16(header.mtime, zip_time);
diff --git a/blame.c b/blame.c
index 8cfd5d94c7..e664813cb4 100644
--- a/blame.c
+++ b/blame.c
@@ -17,19 +17,24 @@
#include "diffcore.h"
#include "revision.h"
#include "xdiff-interface.h"
+#include "quote.h"
#define DEBUG 0
-static const char blame_usage[] = "git-blame [-c] [-l] [-t] [-S <revs-file>] [--] file [commit]\n"
- " -c, --compatibility Use the same output mode as git-annotate (Default: off)\n"
- " -l, --long Show long commit SHA1 (Default: off)\n"
- " -t, --time Show raw timestamp (Default: off)\n"
- " -S, --revs-file Use revisions from revs-file instead of calling git-rev-list\n"
- " -h, --help This message";
+static const char blame_usage[] =
+"git-blame [-c] [-l] [-t] [-f] [-n] [-p] [-S <revs-file>] [--] file [commit]\n"
+" -c, --compatibility Use the same output mode as git-annotate (Default: off)\n"
+" -l, --long Show long commit SHA1 (Default: off)\n"
+" -t, --time Show raw timestamp (Default: off)\n"
+" -f, --show-name Show original filename (Default: auto)\n"
+" -n, --show-number Show original linenumber (Default: off)\n"
+" -p, --porcelain Show in a format designed for machine consumption\n"
+" -S revs-file Use revisions from revs-file instead of calling git-rev-list\n"
+" -h, --help This message";
static struct commit **blame_lines;
static int num_blame_lines;
-static char* blame_contents;
+static char *blame_contents;
static int blame_len;
struct util_info {
@@ -38,9 +43,10 @@ struct util_info {
char *buf;
unsigned long size;
int num_lines;
- const char* pathname;
+ const char *pathname;
+ unsigned meta_given:1;
- void* topo_data;
+ void *topo_data;
};
struct chunk {
@@ -156,11 +162,10 @@ static int get_blob_sha1_internal(const unsigned char *sha1, const char *base,
unsigned mode, int stage);
static unsigned char blob_sha1[20];
-static const char* blame_file;
+static const char *blame_file;
static int get_blob_sha1(struct tree *t, const char *pathname,
unsigned char *sha1)
{
- int i;
const char *pathspec[2];
blame_file = pathname;
pathspec[0] = pathname;
@@ -168,12 +173,7 @@ static int get_blob_sha1(struct tree *t, const char *pathname,
hashclr(blob_sha1);
read_tree_recursive(t, "", 0, 0, pathspec, get_blob_sha1_internal);
- for (i = 0; i < 20; i++) {
- if (blob_sha1[i] != 0)
- break;
- }
-
- if (i == 20)
+ if (is_null_sha1(blob_sha1))
return -1;
hashcpy(sha1, blob_sha1);
@@ -239,7 +239,8 @@ static void print_map(struct commit *cmit, struct commit *other)
if (i < util->num_lines) {
num = util->line_map[i];
printf("%d\t", num);
- } else
+ }
+ else
printf("\t");
if (i < util2->num_lines) {
@@ -247,7 +248,8 @@ static void print_map(struct commit *cmit, struct commit *other)
printf("%d\t", num2);
if (num != -1 && num2 != num)
printf("---");
- } else
+ }
+ else
printf("\t");
printf("\n");
@@ -266,12 +268,12 @@ static void fill_line_map(struct commit *commit, struct commit *other,
int cur_chunk = 0;
int i1, i2;
- if (p->num && DEBUG)
- print_patch(p);
-
- if (DEBUG)
+ if (DEBUG) {
+ if (p->num)
+ print_patch(p);
printf("num lines 1: %d num lines 2: %d\n", util->num_lines,
util2->num_lines);
+ }
for (i1 = 0, i2 = 0; i1 < util->num_lines; i1++, i2++) {
struct chunk *chunk = NULL;
@@ -293,7 +295,8 @@ static void fill_line_map(struct commit *commit, struct commit *other,
i2 += chunk->len2;
cur_chunk++;
- } else {
+ }
+ else {
if (i2 >= util2->num_lines)
break;
@@ -327,19 +330,15 @@ static int map_line(struct commit *commit, int line)
return info->line_map[line];
}
-static struct util_info* get_util(struct commit *commit)
+static struct util_info *get_util(struct commit *commit)
{
struct util_info *util = commit->util;