expansion). These conversions apply when checking files in
or out, and exporting via git-archive.
-* The packfile format now optionally suports 64-bit index.
+* The packfile format now optionally supports 64-bit index.
This release supports the "version 2" format of the .idx
file. This is automatically enabled when a huge packfile
- "git rev-list" learned --regexp-ignore-case and
--extended-regexp options to tweak its matching logic used
- for --grep fitering.
+ for --grep filtering.
- "git describe --contains" is a handier way to call more
obscure command "git name-rev --tags".
- We used to have core.legacyheaders configuration, when
set to false, allowed git to write loose objects in a format
- that mimicks the format used by objects stored in packs. It
+ that mimics the format used by objects stored in packs. It
turns out that this was not so useful. Although we will
continue to read objects written in that format, we do not
honor that configuration anymore and create loose objects in
small enough delta results it creates while looking for the
best delta candidates.
- - "git pack-objects" learned a new heuristcs to prefer delta
+ - "git pack-objects" learned a new heuristic to prefer delta
that is shallower in depth over the smallest delta
possible. This improves both overall packfile access
performance and packfile density.
* "git log --merge" did not work well with --left-right option.
- * "git svn" promprted for client cert password every time it accessed the
+ * "git svn" prompted for client cert password every time it accessed the
server.
* The reset command in "git fast-import" data stream was documented to
1.5.4).
* Bogus refspec configuration such as "remote.there.fetch = =" were not
- detected as errors (regressionin 1.5.4).
+ detected as errors (regression in 1.5.4).
* You couldn't specify a custom editor whose path contains a whitespace
via GIT_EDITOR (and core.editor).
Fixes since v1.5.6.2
--------------------
+* Setting core.sharerepository to traditional "true" value was supposed to make
+ the repository group writable but should not affect permission for others.
+ However, since 1.5.6, it was broken to drop permission for others when umask is
+ 022, making the repository unreadable by others.
+
* Setting GIT_TRACE will report spawning of external process via run_command().
+* Using an object with very deep delta chain pinned memory needed for extracting
+ intermediate base objects unnecessarily long, leading to excess memory usage.
+
* Bash completion script did not notice '--' marker on the command
line and tried the relatively slow "ref completion" even when
completing arguments after one.
tree file for it confused "racy-git avoidance" logic into thinking
that the path is now unchanged.
+* The section that describes attributes related to git-archive were placed
+ in a wrong place in the gitattributes(5) manual page.
+
+* "git am" was not helpful to the users when it detected that the committer
+ information is not set up properly yet.
+
* "git clone" had a leftover debugging fprintf().
* "git clone -q" was not quiet enough as it used to and gave object count
good thing if the remote side is well packed but otherwise not,
especially for a project that is not really big.
-* The section that describes attributes related to git-archive were placed
- in a wrong place in the gitattributes(5) manual page.
+* "git daemon" used to call syslog() from a signal handler, which
+ could raise signals of its own but generally is not reentrant. This
+ was fixed by restructuring the code to report syslog() after the handler
+ returns.
* When "git push" tries to remove a remote ref, and corresponding
tracking ref is missing, we used to report error (i.e. failure to
MIME multipart mail correctly.
Contains other various documentation fixes.
-
---
-exec >/var/tmp/1
-O=v1.5.6.2-23-ge965647
-echo O=$(git describe maint)
-git shortlog --no-merges $O..maint
--- /dev/null
+GIT v1.5.6.4 Release Notes
+==========================
+
+Fixes since v1.5.6.3
+--------------------
+
+* Various commands could overflow its internal buffer on a platform
+ with small PATH_MAX value in a repository that has contents with
+ long pathnames.
+
+* There wasn't a way to make --pretty=format:%<> specifiers to honor
+ .mailmap name rewriting for authors and committers. Now you can with
+ %aN and %cN.
+
+* Bash completion wasted too many cycles; this has been optimized to be
+ usable again.
+
+* Bash completion lost ref part when completing something like "git show
+ pu:Makefile".
+
+* "git-cvsserver" did not clean up its temporary working area after annotate
+ request.
+
+* "git-daemon" called syslog() from its signal handler, which was a
+ no-no.
+
+* "git-fetch" into an empty repository used to remind that the fetch will
+ be huge by saying "no common commits", but this was an unnecessary
+ noise; it is already known by the user anyway.
+
+* "git-http-fetch" would have segfaulted when pack idx file retrieved
+ from the other side was corrupt.
+
+* "git-index-pack" used too much memory when dealing with a deep delta chain.
+
+* "git-mailinfo" (hence "git-am") did not correctly handle in-body [PATCH]
+ line to override the commit title taken from the mail Subject header.
+
+* "git-rebase -i -p" lost parents that are not involved in the history
+ being rewritten.
+
+* "git-rm" lost track of where the index file was when GIT_DIR was
+ specified as a relative path.
+
+* "git-rev-list --quiet" was not quiet as advertised.
+
+Contains other various documentation fixes.
--- /dev/null
+GIT v1.5.6.5 Release Notes
+==========================
+
+Fixes since v1.5.6.4
+--------------------
+
+* "git cvsimport" used to spit out "UNKNOWN LINE..." diagnostics to stdout.
+
+* "git commit -F filename" and "git tag -F filename" run from subdirectories
+ did not read the right file.
+
+* "git init --template=" with blank "template" parameter linked files
+ under root directories to .git, which was a total nonsense. Instead, it
+ means "I do not want to use anything from the template directory".
+
+* "git diff-tree" and other diff plumbing ignored diff.renamelimit configuration
+ variable when the user explicitly asked for rename detection.
+
+* "git name-rev --name-only" did not work when "--stdin" option was in effect.
+
+* "git show-branch" mishandled its 8th branch.
+
+* Addition of "git update-index --ignore-submodules" that happened during
+ 1.5.6 cycle broke "git update-index --ignore-missing".
+
+* "git send-email" did not parse charset from an existing Content-type:
+ header properly.
+
+Contains other various documentation fixes.
# Our diff algorithm
[diff]
- external = "/usr/local/bin/gnu-diff -u"
+ external = /usr/local/bin/diff-wrapper
renames = true
[branch "devel"]
diff.external::
If this config variable is set, diff generation is not
performed using the internal diff machinery, but using the
- given command. Note: if you want to use an external diff
- program only on a subset of your files, you might want to
- use linkgit:gitattributes[5] instead.
+ given command. Can be overridden with the `GIT_EXTERNAL_DIFF'
+ environment variable. The command is called with parameters
+ as described under "git Diffs" in linkgit:git[1]. Note: if
+ you want to use an external diff program only on a subset of
+ your files, you might want to use linkgit:gitattributes[5] instead.
diff.renameLimit::
The number of files to consider when performing the copy/rename
+
or like this (when '--cc' option is used):
- diff --c file
+ diff --cc file
2. It is followed by one or more extended header lines
(this example shows a merge with two parents):
"Update>>". When the prompt ends with double '>>', you can
make more than one selection, concatenated with whitespace or
comma. Also you can say ranges. E.g. "2-5 7,9" to choose
- 2,3,4,5,7,9 from the list. You can say '*' to choose
- everything.
+ 2,3,4,5,7,9 from the list. If the second number in a range is
+ omitted, all remaining patches are taken. E.g. "7-" to choose
+ 7,8,9 from the list. You can say '*' to choose everything.
+
What you chose are then highlighted with '*',
like this:
Author
------
-Written by Junio C Hamano <junkio@cox.net>
+Written by Junio C Hamano <gitster@pobox.com>
Documentation
--------------
AUTHOR
------
-Written by Junio C Hamano <junkio@cox.net>
+Written by Junio C Hamano <gitster@pobox.com>
GIT
---
Author
------
-Written by Linus Torvalds <torvalds@osdl.org> and Junio C Hamano <junkio@cox.net>
+Written by Linus Torvalds <torvalds@osdl.org> and Junio C Hamano <gitster@pobox.com>
Documentation
--------------
Author
------
-Written by Junio C Hamano <junkio@cox.net>
+Written by Junio C Hamano <gitster@pobox.com>
Documentation
--------------
Usually the command automatically creates a commit with
a commit log message stating which commit was
cherry-picked. This flag applies the change necessary
- to cherry-pick the named commit to your working tree,
- but does not make the commit. In addition, when this
- option is used, your working tree does not have to match
+ to cherry-pick the named commit to your working tree
+ and the index, but does not make the commit. In addition,
+ when this option is used, your index does not have to match
the HEAD commit. The cherry-pick is done against the
- beginning state of your working tree.
+ beginning state of your index.
+
This is useful when cherry-picking more than one commits'
-effect to your working tree in a row.
+effect to your index in a row.
-s::
--signoff::
Author
------
-Written by Junio C Hamano <junkio@cox.net>
+Written by Junio C Hamano <gitster@pobox.com>
Documentation
--------------
Author
------
-Written by Junio C Hamano <junkio@cox.net>
+Written by Junio C Hamano <gitster@pobox.com>
Documentation
--------------
Author
------
Written by Linus Torvalds <torvalds@osdl.org> and
-Junio C Hamano <junkio@cox.net>
+Junio C Hamano <gitster@pobox.com>
GIT
; Our diff algorithm
[diff]
- external = "/usr/local/bin/gnu-diff -u"
+ external = /usr/local/bin/diff-wrapper
renames = true
; Proxy settings
Author
------
-Written by Junio C Hamano <junkio@cox.net>
+Written by Junio C Hamano <gitster@pobox.com>
Documentation
--------------
Author
------
Written by Linus Torvalds <torvalds@osdl.org>, but somewhat
-butchered by Junio C Hamano <junkio@cox.net>. Later significantly
+butchered by Junio C Hamano <gitster@pobox.com>. Later significantly
updated by Shawn Pearce <spearce@spearce.org>.
Documentation
--stdin::
When '--stdin' is specified, the command does not take
<tree-ish> arguments from the command line. Instead, it
- reads either one <commit> or a pair of <tree-ish>
+ reads either one <commit> or a list of <commit>
separated with a single space from its standard input.
+
When a single commit is given on one line of such input, it compares
the commit with its parents. The following flags further affects its
-behavior. This does not apply to the case where two <tree-ish>
-separated with a single space are given.
+behavior. The remaining commits, when given, are used as if they are
+parents of the first commit.
-m::
By default, "git-diff-tree --stdin" does not show
This flag changes the way a merge commit patch is displayed,
in a similar way to the '-c' option. It implies the '-c'
and '-p' options and further compresses the patch output
- by omitting hunks that show differences from only one
- parent, or show the same change from all but one parent
- for an Octopus merge. When this optimization makes all
- hunks disappear, the commit itself and the commit log
- message is not shown, just like in any other "empty diff" case.
+ by omitting uninteresting hunks whose the contents in the parents
+ have only two variants and the merge result picks one of them
+ without modification. When all hunks are uninteresting, the commit
+ itself and the commit log message is not shown, just like in any other
+ "empty diff" case.
--always::
Show the commit itself and the commit log message even
Author
------
Written by Linus Torvalds <torvalds@osdl.org> and
-Junio C Hamano <junkio@cox.net>
+Junio C Hamano <gitster@pobox.com>
Documentation
-------------
Author
------
-Written by Junio C Hamano <junkio@cox.net>
+Written by Junio C Hamano <gitster@pobox.com>
Documentation
--------------
Author
------
-Written by Junio C Hamano <junkio@cox.net>
+Written by Junio C Hamano <gitster@pobox.com>
Documentation
--------------
Author
------
-Written by Junio C Hamano <junkio@cox.net>
+Written by Junio C Hamano <gitster@pobox.com>
Documentation
--------------
Author
------
-Written by Junio C Hamano <junkio@cox.net>
+Written by Junio C Hamano <gitster@pobox.com>
GIT
---
Author
------
Written by Petr Baudis <pasky@suse.cz>
-Completely rewritten from scratch by Junio C Hamano <junkio@cox.net>,
+Completely rewritten from scratch by Junio C Hamano <gitster@pobox.com>,
another major rewrite by Linus Torvalds <torvalds@osdl.org>
Documentation
SYNOPSIS
--------
-'git-mailinfo' [-k] [-u | --encoding=<encoding>] <msg> <patch>
+'git-mailinfo' [-k] [-u | --encoding=<encoding> | -n] <msg> <patch>
DESCRIPTION
from what is specified by i18n.commitencoding, this flag
can be used to override it.
+-n::
+ Disable all charset re-coding of the metadata.
+
<msg>::
The commit log message extracted from e-mail, usually
except the title line which comes from e-mail Subject.
Author
------
Written by Linus Torvalds <torvalds@osdl.org> and
-Junio C Hamano <junkio@cox.net>
+Junio C Hamano <gitster@pobox.com>
Documentation
Author
------
Written by Linus Torvalds <torvalds@osdl.org>
-and Junio C Hamano <junkio@cox.net>
+and Junio C Hamano <gitster@pobox.com>
Documentation
Author
------
Written by Linus Torvalds <torvalds@osdl.org>,
-Junio C Hamano <junkio@cox.net> and Petr Baudis <pasky@suse.cz>.
+Junio C Hamano <gitster@pobox.com> and Petr Baudis <pasky@suse.cz>.
Documentation
--------------
Author
------
-Written by Junio C Hamano <junkio@cox.net>
+Written by Junio C Hamano <gitster@pobox.com>
Documentation
Author
------
-Written by Junio C Hamano <junkio@cox.net>
+Written by Junio C Hamano <gitster@pobox.com>
Documentation
--------------
Instead of printing both the SHA-1 and the name, print only
the name. If given with --tags the usual tag prefix of
"tags/" is also omitted from the name, matching the output
- of linkgit:git-describe[1] more closely. This option
- cannot be combined with --stdin.
+ of linkgit:git-describe[1] more closely.
--no-undefined::
Die with error code != 0 when a reference is undefined,
Author
------
-Written by Junio C Hamano <junkio@cox.net>
+Written by Junio C Hamano <gitster@pobox.com>
Documentation
--------------
Author
------
Written by Linus Torvalds <torvalds@osdl.org>
-and Junio C Hamano <junkio@cox.net>
+and Junio C Hamano <gitster@pobox.com>
Documentation
--------------
Author
------
-Written by Junio C Hamano <junkio@cox.net>, later rewritten in C
+Written by Junio C Hamano <gitster@pobox.com>, later rewritten in C
by Linus Torvalds <torvalds@osdl.org>
Documentation
Authors
------
-Written by Junio C Hamano <junkio@cox.net> and
+Written by Junio C Hamano <gitster@pobox.com> and
Johannes E. Schindelin <johannes.schindelin@gmx.de>
Documentation
Author
------
-Written by Junio C Hamano <junkio@cox.net>
+Written by Junio C Hamano <gitster@pobox.com>
Documentation
--------------
Author
------
-Written by Ryan Anderson <ryan@michonline.com> and Junio C Hamano <junkio@cox.net>
+Written by Ryan Anderson <ryan@michonline.com> and Junio C Hamano <gitster@pobox.com>
Documentation
--------------
Author
------
-Written by Junio C Hamano <junkio@cox.net>
+Written by Junio C Hamano <gitster@pobox.com>
GIT
---
Author
------
-Written by Junio C Hamano <junkio@cox.net> and Linus Torvalds <torvalds@osdl.org>
+Written by Junio C Hamano <gitster@pobox.com> and Linus Torvalds <torvalds@osdl.org>
Documentation
--------------
Author
------
Written by Linus Torvalds <torvalds@osdl.org> .
-Junio C Hamano <junkio@cox.net> and Pierre Habouzit <madcoder@debian.org>
+Junio C Hamano <gitster@pobox.com> and Pierre Habouzit <madcoder@debian.org>
Documentation
--------------
-n::
--no-commit::
Usually the command automatically creates a commit with
- a commit log message stating which commit was reverted.
- This flag applies the change necessary to revert the
- named commit to your working tree, but does not make the
- commit. In addition, when this option is used, your
- working tree does not have to match the HEAD commit.
- The revert is done against the beginning state of your
- working tree.
+ a commit log message stating which commit was
+ reverted. This flag applies the change necessary
+ to revert the named commit to your working tree
+ and the index, but does not make the commit. In addition,
+ when this option is used, your index does not have to match
+ the HEAD commit. The revert is done against the
+ beginning state of your index.
+
This is useful when reverting more than one commits'
-effect to your working tree in a row.
+effect to your index in a row.
-s::
--signoff::
Author
------
-Written by Junio C Hamano <junkio@cox.net>
+Written by Junio C Hamano <gitster@pobox.com>
Documentation
--------------
Author
------
-Written by Junio C Hamano <junkio@cox.net>
+Written by Junio C Hamano <gitster@pobox.com>
Documentation
Author
------
Written by Linus Torvalds <torvalds@osdl.org> and
-Junio C Hamano <junkio@cox.net>. Significantly enhanced by
+Junio C Hamano <gitster@pobox.com>. Significantly enhanced by
Johannes Schindelin <Johannes.Schindelin@gmx.de>.
Author
------
Written by Linus Torvalds <torvalds@osdl.org> and
-Junio C Hamano <junkio@cox.net>.
+Junio C Hamano <gitster@pobox.com>.
Documentation
--------------
Author
------
-Written by Junio C Hamano <junkio@cox.net>
+Written by Junio C Hamano <gitster@pobox.com>
GIT
---
Author
------
Written by Linus Torvalds <torvalds@osdl.org>,
-Junio C Hamano <junkio@cox.net> and Chris Wright <chrisw@osdl.org>.
+Junio C Hamano <gitster@pobox.com> and Chris Wright <chrisw@osdl.org>.
Documentation
--------------
Author
------
-Written by Junio C Hamano <junkio@cox.net>
+Written by Junio C Hamano <gitster@pobox.com>
Documentation
--------------
Author
------
-Written by Junio C Hamano <junkio@cox.net>
+Written by Junio C Hamano <gitster@pobox.com>
Documentation
--------------
Author
------
Written by Linus Torvalds <torvalds@osdl.org> and
-Junio C Hamano <junkio@cox.net>
+Junio C Hamano <gitster@pobox.com>
Documentation
branch of the `git.git` repository.
Documentation for older releases are available here:
-* link:v1.5.6.2/git.html[documentation for release 1.5.6.2]
+* link:v1.5.6.5/git.html[documentation for release 1.5.6.5]
* release notes for
- link:RelNotes-1.5.6.2.txt[1.5.6.2].
- link:RelNotes-1.5.6.1.txt[1.5.6.1].
+ link:RelNotes-1.5.6.5.txt[1.5.6.5],
+ link:RelNotes-1.5.6.4.txt[1.5.6.4],
+ link:RelNotes-1.5.6.3.txt[1.5.6.3],
+ link:RelNotes-1.5.6.2.txt[1.5.6.2],
+ link:RelNotes-1.5.6.1.txt[1.5.6.1],
link:RelNotes-1.5.6.txt[1.5.6].
* link:v1.5.5.4/git.html[documentation for release 1.5.5.4]
-From: Junio C Hamano <junkio@cox.net>
+From: Junio C Hamano <gitster@pobox.com>
To: git@vger.kernel.org
Cc: Petr Baudis <pasky@suse.cz>, Linus Torvalds <torvalds@osdl.org>
Subject: Re: sending changesets from the middle of a git tree
Subject: [HOWTO] Using post-update hook
Message-ID: <7vy86o6usx.fsf@assigned-by-dhcp.cox.net>
-From: Junio C Hamano <junkio@cox.net>
+From: Junio C Hamano <gitster@pobox.com>
Date: Fri, 26 Aug 2005 18:19:10 -0700
Abstract: In this how-to article, JC talks about how he
uses the post-update hook to automate git documentation page
-From: Junio C Hamano <junkio@cox.net>
+From: Junio C Hamano <gitster@pobox.com>
To: git@vger.kernel.org
Subject: [HOWTO] Reverting an existing commit
Abstract: In this article, JC gives a small real-life example of using
-From: Junio C Hamano <junkio@cox.net>
+From: Junio C Hamano <gitster@pobox.com>
Subject: Separating topic branches
Abstract: In this article, JC describes how to separate topic branches.
-From: Junio C Hamano <junkio@cox.net> and Carl Baldwin <cnb@fc.hp.com>
+From: Junio C Hamano <gitster@pobox.com> and Carl Baldwin <cnb@fc.hp.com>
Subject: control access to branches.
Date: Thu, 17 Nov 2005 23:55:32 -0800
Message-ID: <7vfypumlu3.fsf@assigned-by-dhcp.cox.net>
- '%P': parent hashes
- '%p': abbreviated parent hashes
- '%an': author name
+- '%aN': author name (respecting .mailmap)
- '%ae': author email
- '%ad': author date
- '%aD': author date, RFC2822 style
- '%at': author date, UNIX timestamp
- '%ai': author date, ISO 8601 format
- '%cn': committer name
+- '%cN': committer name (respecting .mailmap)
- '%ce': committer email
- '%cd': committer date
- '%cD': committer date, RFC2822 style
--cc::
This flag implies the '-c' options and further compresses the
- patch output by omitting hunks that show differences from only
- one parent, or show the same change from all but one parent for
- an Octopus merge.
+ patch output by omitting uninteresting hunks whose contents in
+ the parents have only two variants and the merge result picks
+ one of them without modification.
-r::
start_command() followed by finish_command(). Takes a pointer
to a `struct child_process` that specifies the details.
-`run_command_v_opt`, `run_command_v_opt_dir`, `run_command_v_opt_cd_env`::
+`run_command_v_opt`, `run_command_v_opt_cd`, `run_command_v_opt_cd_env`::
Convenience functions that encapsulate a sequence of
start_command() followed by finish_command(). The argument argv
#!/bin/sh
GVF=GIT-VERSION-FILE
-DEF_VER=v1.5.6.GIT
+DEF_VER=v1.5.6.5.GIT
LF='
'
echo "$$FLAGS" >GIT-CFLAGS; \
fi
+# We need to apply sq twice, once to protect from the shell
+# that runs GIT-BUILD-OPTIONS, and then again to protect it
+# and the first level quoting from the shell that runs "echo".
GIT-BUILD-OPTIONS: .FORCE-GIT-BUILD-OPTIONS
- @echo SHELL_PATH=\''$(SHELL_PATH_SQ)'\' >$@
+ @echo SHELL_PATH=\''$(subst ','\'',$(SHELL_PATH_SQ))'\' >$@
+ @echo TAR=\''$(subst ','\'',$(subst ','\'',$(TAR)))'\' >>$@
### Detect Tck/Tk interpreter path changes
ifndef NO_TCLTK
-Documentation/RelNotes-1.5.6.3.txt
\ No newline at end of file
+Documentation/RelNotes-1.5.6.5.txt
\ No newline at end of file
{
struct attr_stack *elem, *info;
int len;
- char pathbuf[PATH_MAX];
+ struct strbuf pathbuf;
+
+ strbuf_init(&pathbuf, dirlen+2+strlen(GITATTRIBUTES_FILE));
/*
* At the bottom of the attribute stack is the built-in
len = strlen(attr_stack->origin);
if (dirlen <= len)
break;
- memcpy(pathbuf, path, dirlen);
- memcpy(pathbuf + dirlen, "/", 2);
- cp = strchr(pathbuf + len + 1, '/');
+ strbuf_reset(&pathbuf);
+ strbuf_add(&pathbuf, path, dirlen);
+ strbuf_addch(&pathbuf, '/');
+ cp = strchr(pathbuf.buf + len + 1, '/');
strcpy(cp + 1, GITATTRIBUTES_FILE);
- elem = read_attr(pathbuf, 0);
+ elem = read_attr(pathbuf.buf, 0);
*cp = '\0';
- elem->origin = strdup(pathbuf);
+ elem->origin = strdup(pathbuf.buf);
elem->prev = attr_stack;
attr_stack = elem;
debug_push(elem);
opts.track = git_branch_track;
- argc = parse_options(argc, argv, options, checkout_usage, 0);
+ argc = parse_options(argc, argv, options, checkout_usage,
+ PARSE_OPT_KEEP_DASHDASH);
if (argc) {
arg = argv[0];
if (get_sha1(arg, rev))
if (option_quiet)
transport->verbose = -1;
+ if (option_upload_pack)
+ transport_set_option(transport, TRANS_OPT_UPLOADPACK,
+ option_upload_pack);
+
refs = transport_get_remote_refs(transport);
transport_fetch_refs(transport, refs);
}
COMMIT_PARTIAL,
} commit_style;
-static char *logfile, *force_author;
+static const char *logfile, *force_author;
static const char *template_file;
static char *edit_message, *use_message;
static char *author_name, *author_email, *author_date;
}
static int parse_and_validate_options(int argc, const char *argv[],
- const char * const usage[])
+ const char * const usage[],
+ const char *prefix)
{
int f = 0;
argc = parse_options(argc, argv, builtin_commit_options, usage, 0);
+ logfile = parse_options_fix_filename(prefix, logfile);
+ template_file = parse_options_fix_filename(prefix, template_file);
if (logfile || message.len || use_message)
use_editor = 0;
if (wt_status_use_color == -1)
wt_status_use_color = git_use_color_default;
- argc = parse_and_validate_options(argc, argv, builtin_status_usage);
+ argc = parse_and_validate_options(argc, argv, builtin_status_usage, prefix);
index_file = prepare_index(argc, argv, prefix);
git_config(git_commit_config, NULL);
- argc = parse_and_validate_options(argc, argv, builtin_commit_usage);
+ argc = parse_and_validate_options(argc, argv, builtin_commit_usage, prefix);
index_file = prepare_index(argc, argv, prefix);
}
flushes--;
}
- return retval;
+ /* it is no error to fetch into a completely empty repo */
+ return count ? retval : 0;
}
static struct commit_list *complete;
struct name_entry entry;
char *down;
int tn_len = strlen(tree_name);
- char *path_buf = xmalloc(PATH_MAX + tn_len + 100);
+ struct strbuf pathbuf;
+
+ strbuf_init(&pathbuf, PATH_MAX + tn_len);
if (tn_len) {
- tn_len = sprintf(path_buf, "%s:", tree_name);
- down = path_buf + tn_len;
- strcat(down, base);
- }
- else {
- down = path_buf;
- strcpy(down, base);
+ strbuf_add(&pathbuf, tree_name, tn_len);
+ strbuf_addch(&pathbuf, ':');
+ tn_len = pathbuf.len;
}
- len = strlen(path_buf);
+ strbuf_addstr(&pathbuf, base);
+ len = pathbuf.len;
while (tree_entry(tree, &entry)) {
- strcpy(path_buf + len, entry.path);
+ int te_len = tree_entry_len(entry.path, entry.sha1);
+ pathbuf.len = len;
+ strbuf_add(&pathbuf, entry.path, te_len);
if (S_ISDIR(entry.mode))
/* Match "abc/" against pathspec to
* decide if we want to descend into "abc"
* directory.
*/
- strcpy(path_buf + len + tree_entry_len(entry.path, entry.sha1), "/");
+ strbuf_addch(&pathbuf, '/');
+ down = pathbuf.buf + tn_len;
if (!pathspec_matches(paths, down))
;
else if (S_ISREG(entry.mode))
- hit |= grep_sha1(opt, entry.sha1, path_buf, tn_len);
+ hit |= grep_sha1(opt, entry.sha1, pathbuf.buf, tn_len);
else if (S_ISDIR(entry.mode)) {
enum object_type type;
struct tree_desc sub;
free(data);
}
}
+ strbuf_release(&pathbuf);
return hit;
}
}
static const char builtin_grep_usage[] =
-"git-grep <option>* <rev>* [-e] <pattern> [<path>...]";
+"git-grep <option>* [-e] <pattern> <rev>* [[--] <path>...]";
static const char emsg_invalid_context_len[] =
"%s: invalid context length argument";
template_dir = strbuf_detach(&d, NULL);
}
}
+ if (!template_dir[0])
+ return;
strcpy(template_path, template_dir);
template_len = strlen(template_path);
if (template_path[template_len-1] != '/') {
return 1;
if (!memcmp("[PATCH]", line, 7) && isspace(line[7])) {
for (i = 0; header[i]; i++) {
- if (!memcmp("Subject: ", header[i], 9)) {
+ if (!memcmp("Subject", header[i], 7)) {
+ if (!hdr_data[i])
+ hdr_data[i] = xmalloc(linesize + 20);
if (! handle_header(line, hdr_data[i], 0)) {
return 1;
}
}
static const char mailinfo_usage[] =
- "git-mailinfo [-k] [-u | --encoding=<encoding>] msg patch <mail >info";
+ "git-mailinfo [-k] [-u | --encoding=<encoding> | -n] msg patch <mail >info";
int cmd_mailinfo(int argc, const char **argv, const char *prefix)
{
NULL
};
+static void name_rev_line(char *p, struct name_ref_data *data)
+{
+ int forty = 0;
+ char *p_start;
+ for (p_start = p; *p; p++) {
+#define ishex(x) (isdigit((x)) || ((x) >= 'a' && (x) <= 'f'))
+ if (!ishex(*p))
+ forty = 0;
+ else if (++forty == 40 &&
+ !ishex(*(p+1))) {
+ unsigned char sha1[40];
+ const char *name = NULL;
+ char c = *(p+1);
+ int p_len = p - p_start + 1;
+
+ forty = 0;
+
+ *(p+1) = 0;
+ if (!get_sha1(p - 39, sha1)) {
+ struct object *o =
+ lookup_object(sha1);
+ if (o)
+ name = get_rev_name(o);
+ }
+ *(p+1) = c;
+
+ if (!name)
+ continue;
+
+ if (data->name_only)
+ printf("%.*s%s", p_len - 40, p_start, name);
+ else
+ printf("%.*s (%s)", p_len, p_start, name);
+ p_start = p + 1;
+ }
+ }
+
+ /* flush */
+ if (p_start != p)
+ fwrite(p_start, p - p_start, 1, stdout);
+}
+
int cmd_name_rev(int argc, const char **argv, const char *prefix)
{
struct object_array revs = { 0, 0, NULL };
if (transform_stdin) {
char buffer[2048];
- char *p, *p_start;
while (!feof(stdin)) {
- int forty = 0;
- p = fgets(buffer, sizeof(buffer), stdin);
+ char *p = fgets(buffer, sizeof(buffer), stdin);
if (!p)
break;
-
- for (p_start = p; *p; p++) {
-#define ishex(x) (isdigit((x)) || ((x) >= 'a' && (x) <= 'f'))
- if (!ishex(*p))
- forty = 0;
- else if (++forty == 40 &&
- !ishex(*(p+1))) {
- unsigned char sha1[40];
- const char *name = NULL;
- char c = *(p+1);
-
- forty = 0;
-
- *(p+1) = 0;
- if (!get_sha1(p - 39, sha1)) {
- struct object *o =
- lookup_object(sha1);
- if (o)
- name = get_rev_name(o);
- }
- *(p+1) = c;
-
- if (!name)
- continue;
-
- fwrite(p_start, p - p_start + 1, 1, stdout);
- printf(" (%s)", name);
- p_start = p + 1;
- }
- }
-
- /* flush */
- if (p_start != p)
- fwrite(p_start, p - p_start, 1, stdout);
+ name_rev_line(p, &data);
}
} else if (all) {
int i, max;
revs.commit_format = CMIT_FMT_UNSPECIFIED;
argc = setup_revisions(argc, argv, &revs, NULL);
+ quiet = DIFF_OPT_TST(&revs.diffopt, QUIET);
for (i = 1 ; i < argc; i++) {
const char *arg = argv[i];
read_revisions_from_stdin(&revs);
continue;
}
- if (!strcmp(arg, "--quiet")) {
- quiet = 1;
- continue;
- }
usage(rev_list_usage);
}
email++;
timestamp = strchr(email, '>');
if (!timestamp)
- die ("Could not extract author email from %s",
+ die ("Could not extract author time from %s",
sha1_to_hex(commit->object.sha1));
*timestamp = '\0';
for (timestamp++; *timestamp && isspace(*timestamp);
git_config(git_default_config, NULL);
- newfd = hold_locked_index(&lock_file, 1);
-
- if (read_cache() < 0)
- die("index file corrupt");
-
argc = parse_options(argc, argv, builtin_rm_options, builtin_rm_usage, 0);
if (!argc)
usage_with_options(builtin_rm_usage, builtin_rm_options);
if (!index_only)
setup_work_tree();
+ newfd = hold_locked_index(&lock_file, 1);
+
+ if (read_cache() < 0)
+ die("index file corrupt");
+
pathspec = get_pathspec(prefix, argv);
seen = NULL;
for (i = 0; pathspec[i] ; i++)
int annotate = 0, sign = 0, force = 0, lines = 0,
list = 0, delete = 0, verify = 0;
- char *msgfile = NULL, *keyid = NULL;
+ const char *msgfile = NULL, *keyid = NULL;
struct msg_arg msg = { 0, STRBUF_INIT };
struct option options[] = {
OPT_BOOLEAN('l', NULL, &list, "list tag names"),
git_config(git_tag_config, NULL);
argc = parse_options(argc, argv, options, git_tag_usage, 0);
+ msgfile = parse_options_fix_filename(prefix, msgfile);
if (keyid) {
sign = 1;
#define REFRESH_UNMERGED 0x0002 /* allow unmerged */
#define REFRESH_QUIET 0x0004 /* be quiet about it */
#define REFRESH_IGNORE_MISSING 0x0008 /* ignore non-existent */
-#define REFRESH_IGNORE_SUBMODULES 0x0008 /* ignore submodules */
+#define REFRESH_IGNORE_SUBMODULES 0x0010 /* ignore submodules */
extern int refresh_index(struct index_state *, unsigned int flags, const char **pathspec, char *seen);
struct lock_file {
/* Mark them and clear the indegree */
for (next = orig; next; next = next->next) {
struct commit *commit = next->item;
- commit->object.flags |= TOPOSORT;
- commit->indegree = 0;
+ commit->indegree = 1;
}
/* update the indegree */
while (parents) {
struct commit *parent = parents->item;
- if (parent->object.flags & TOPOSORT)
+ if (parent->indegree)
parent->indegree++;
parents = parents->next;
}
for (next = orig; next; next = next->next) {
struct commit *commit = next->item;
- if (!commit->indegree)
+ if (commit->indegree == 1)
insert = &commit_list_insert(commit, insert)->next;
}
for (parents = commit->parents; parents ; parents = parents->next) {
struct commit *parent=parents->item;
- if (!(parent->object.flags & TOPOSORT))
+ if (!parent->indegree)
continue;
/*
* when all their children have been emitted thereby
* guaranteeing topological order.
*/
- if (!--parent->indegree) {
+ if (--parent->indegree == 1) {
if (!lifo)
insert_by_date(parent, &work);
else
* work_item is a commit all of whose children
* have already been emitted. we can emit it now.
*/
- commit->object.flags &= ~TOPOSORT;
+ commit->indegree = 0;
*pptr = work_item;
pptr = &work_item->next;
}
# git@vger.kernel.org
#
+case "$COMP_WORDBREAKS" in
+*:*) : great ;;
+*) COMP_WORDBREAKS="$COMP_WORDBREAKS:"
+esac
+
__gitdir ()
{
if [ -z "$1" ]; then
fi
}
+__gitcomp_1 ()
+{
+ local c IFS=' '$'\t'$'\n'
+ for c in $1; do
+ case "$c$2" in
+ --*=*) printf %s$'\n' "$c$2" ;;
+ *.) printf %s$'\n' "$c$2" ;;
+ *) printf %s$'\n' "$c$2 " ;;
+ esac
+ done
+}
+
__gitcomp ()
{
- local all c s=$'\n' IFS=' '$'\t'$'\n'
local cur="${COMP_WORDS[COMP_CWORD]}"
if [ $# -gt 2 ]; then
cur="$3"
case "$cur" in
--*=)
COMPREPLY=()
- return
;;
*)
- for c in $1; do
- case "$c$4" in
- --*=*) all="$all$c$4$s" ;;
- *.) all="$all$c$4$s" ;;
- *) all="$all$c$4 $s" ;;
- esac
- done
+ local IFS=$'\n'
+ COMPREPLY=($(compgen -P "$2" \
+ -W "$(__gitcomp_1 "$1" "$4")" \
+ -- "$cur"))
;;
esac
- IFS=$s
- COMPREPLY=($(compgen -P "$2" -W "$all" -- "$cur"))
- return
}
__git_heads ()
ls="$ref"
;;
esac
+
+ case "$COMP_WORDBREAKS" in
+ *:*) : great ;;
+ *) pfx="$ref:$pfx" ;;
+ esac
+
+ local IFS=$'\n'
COMPREPLY=($(compgen -P "$pfx" \
-W "$(git --git-dir="$(__gitdir)" ls-tree "$ls" \
- | sed '/^100... blob /s,^.* ,,
+ | sed '/^100... blob /{
+ s,^.* ,,
+ s,$, ,
+ }
+ /^120000 blob /{
+ s,^.* ,,
+ s,$, ,
+ }
/^040000 tree /{
s,^.* ,,
s,$,/,
cur="${cur#*..}"
__gitcomp "$(__git_refs)" "$pfx" "$cur"
;;
- *.)
- __gitcomp "$cur."
- ;;
*)
__gitcomp "$(__git_refs)"
;;
*)
case "$cur" in
*:*)
- __gitcomp "$(__git_refs)" "" "${cur#*:}"
+ local pfx=""
+ case "$COMP_WORDBREAKS" in
+ *:*) : great ;;
+ *) pfx="${cur%%:*}:" ;;
+ esac
+ __gitcomp "$(__git_refs)" "$pfx" "${cur#*:}"
;;
*)
local remote
git-push) remote="${COMP_WORDS[1]}" ;;
git) remote="${COMP_WORDS[2]}" ;;
esac
- __gitcomp "$(__git_refs "$remote")" "" "${cur#*:}"
+
+ local pfx=""
+ case "$COMP_WORDBREAKS" in
+ *:*) : great ;;
+ *) pfx="${cur%%:*}:" ;;
+ esac
+
+ __gitcomp "$(__git_refs "$remote")" "$pfx" "${cur#*:}"
;;
+*)
__gitcomp "$(__git_refs)" + "${cur#+}"
}
}
+static void check_dead_children(void)
+{
+ unsigned spawned, reaped, deleted;
+
+ spawned = children_spawned;
+ reaped = children_reaped;
+ deleted = children_deleted;
+
+ while (deleted < reaped) {
+ pid_t pid = dead_child[deleted % MAX_CHILDREN];
+ const char *dead = pid < 0 ? " (with error)" : "";
+
+ if (pid < 0)
+ pid = -pid;
+
+ /* XXX: Custom logging, since we don't wanna getpid() */
+ if (verbose) {
+ if (log_syslog)
+ syslog(LOG_INFO, "[%d] Disconnected%s",
+ pid, dead);
+ else
+ fprintf(stderr, "[%d] Disconnected%s\n",
+ pid, dead);
+ }
+ remove_child(pid, deleted, spawned);
+ deleted++;
+ }
+ children_deleted = deleted;
+}
+
static void check_max_connections(void)
{
for (;;) {
int active;
- unsigned spawned, reaped, deleted;
+ unsigned spawned, deleted;
+
+ check_dead_children();
spawned = children_spawned;
- reaped = children_reaped;
deleted = children_deleted;
- while (deleted < reaped) {
- pid_t pid = dead_child[deleted % MAX_CHILDREN];
- remove_child(pid, deleted, spawned);
- deleted++;
- }
- children_deleted = deleted;
-
active = spawned - deleted;
if (active <= max_connections)
break;
if (pid > 0) {
unsigned reaped = children_reaped;
+ if (!WIFEXITED(status) || WEXITSTATUS(status) > 0)
+ pid = -pid;
dead_child[reaped % MAX_CHILDREN] = pid;
children_reaped = reaped + 1;
- /* XXX: Custom logging, since we don't wanna getpid() */
- if (verbose) {
- const char *dead = "";
- if (!WIFEXITED(status) || WEXITSTATUS(status) > 0)
- dead = " (with error)";
- if (log_syslog)
- syslog(LOG_INFO, "[%d] Disconnected%s", pid, dead);
- else
- fprintf(stderr, "[%d] Disconnected%s\n", pid, dead);
- }
continue;
}
break;
for (;;) {
int i;
+ int timeout;
- if (poll(pfd, socknum, -1) < 0) {
+ /*
+ * This 1-sec timeout could lead to idly looping but it is
+ * here so that children culled in child_handler() are reported
+ * without too much delay. We could probably set up a pipe
+ * to ourselves that we poll, and write to the fd from child_handler()
+ * to wake us up (and consume it when the poll() returns...
+ */
+ timeout = (children_spawned != children_deleted) ? 1000 : -1;
+ i = poll(pfd, socknum, timeout);
+ if (i < 0) {
if (errno != EINTR) {
error("poll failed, resuming: %s",
strerror(errno));
}
continue;
}
+ if (i == 0) {
+ check_dead_children();
+ continue;
+ }
for (i = 0; i < socknum; i++) {
if (pfd[i].revents & POLLIN) {
if (silent_on_removed)
continue;
diff_addremove(&revs->diffopt, '-', ce->ce_mode,
- ce->sha1, ce->name, NULL);
+ ce->sha1, ce->name);
continue;
}
changed = ce_match_stat(ce, &st, ce_option);
newmode = ce_mode_from_stat(ce, st.st_mode);
diff_change(&revs->diffopt, oldmode, newmode,
ce->sha1, (changed ? null_sha1 : ce->sha1),
- ce->name, NULL);
+ ce->name);
}
diffcore_std(&revs->diffopt);
const unsigned char *sha1, unsigned int mode)
{
diff_addremove(&revs->diffopt, prefix[0], mode,
- sha1, ce->name, NULL);
+ sha1, ce->name);
}
static int get_stat_data(struct cache_entry *ce,
return 0;
diff_change(&revs->diffopt, oldmode, mode,
- old->sha1, sha1, old->name, NULL);
+ old->sha1, sha1, old->name);
return 0;
}
*/
int git_diff_ui_config(const char *var, const char *value, void *cb)
{
- if (!strcmp(var, "diff.renamelimit")) {
- diff_rename_limit_default = git_config_int(var, value);
- return 0;
- }
if (!strcmp(var, "diff.color") || !strcmp(var, "color.diff")) {
diff_use_color_default = git_config_colorbool(var, value, -1);
return 0;
int git_diff_basic_config(const char *var, const char *value, void *cb)
{
+ if (!strcmp(var, "diff.renamelimit")) {
+ diff_rename_limit_default = git_config_int(var, value);
+ return 0;
+ }
+
if (!prefixcmp(var, "diff.color.") || !prefixcmp(var, "color.diff.")) {
int slot = parse_diff_color_slot(var, 11);
if (!value)
void diff_addremove(struct diff_options *options,
int addremove, unsigned mode,
const unsigned char *sha1,
- const char *base, const char *path)
+ const char *concatpath)
{
- char concatpath[PATH_MAX];
struct diff_filespec *one, *two;
if (DIFF_OPT_TST(options, IGNORE_SUBMODULES) && S_ISGITLINK(mode))
addremove = (addremove == '+' ? '-' :
addremove == '-' ? '+' : addremove);
- if (!path) path = "";
- sprintf(concatpath, "%s%s", base, path);
-
if (options->prefix &&
strncmp(concatpath, options->prefix, options->prefix_length))
return;
unsigned old_mode, unsigned new_mode,
const unsigned char *old_sha1,
const unsigned char *new_sha1,
- const char *base, const char *path)
+ const char *concatpath)
{
- char concatpath[PATH_MAX];
struct diff_filespec *one, *two;
if (DIFF_OPT_TST(options, IGNORE_SUBMODULES) && S_ISGITLINK(old_mode)
tmp = old_mode; old_mode = new_mode; new_mode = tmp;
tmp_c = old_sha1; old_sha1 = new_sha1; new_sha1 = tmp_c;
}
- if (!path) path = "";
- sprintf(concatpath, "%s%s", base, path);
if (options->prefix &&
strncmp(concatpath, options->prefix, options->prefix_length))
unsigned old_mode, unsigned new_mode,
const unsigned char *old_sha1,
const unsigned char *new_sha1,
- const char *base, const char *path);
+ const char *fullpath);
typedef void (*add_remove_fn_t)(struct diff_options *options,
int addremove, unsigned mode,
const unsigned char *sha1,
- const char *base, const char *path);
+ const char *fullpath);
typedef void (*diff_format_fn_t)(struct diff_queue_struct *q,
struct diff_options *options, void *data);
int addremove,
unsigned mode,
const unsigned char *sha1,
- const char *base,
- const char *path);
+ const char *fullpath);
extern void diff_change(struct diff_options *,
unsigned mode1, unsigned mode2,
const unsigned char *sha1,
const unsigned char *sha2,
- const char *base, const char *path);
+ const char *fullpath);
extern void diff_unmerge(struct diff_options *,
const char *path,
if ($choice =~ s/^-//) {
$choose = 0;
}
- # A range can be specified like 5-7
- if ($choice =~ /^(\d+)-(\d+)$/) {
- ($bottom, $top) = ($1, $2);
+ # A range can be specified like 5-7 or 5-.
+ if ($choice =~ /^(\d+)-(\d*)$/) {
+ ($bottom, $top) = ($1, length($2) ? $2 : 1 + @stuff);
}
elsif ($choice =~ /^\d+$/) {
$bottom = $top = $choice;
require_work_tree
cd_to_toplevel
-git var GIT_COMMITTER_IDENT >/dev/null || exit
+git var GIT_COMMITTER_IDENT >/dev/null ||
+ die "You need to set your committer info first"
stop_here () {
echo "$1" >"$dotest/next"
} elsif (/^-+$/) { # end of unknown-line processing
$state = 1;
} elsif ($state != 11) { # ignore stuff when skipping
- print "* UNKNOWN LINE * $_\n";
+ print STDERR "* UNKNOWN LINE * $_\n";
}
}
commit() if $branch and $state != 11;
}
# done; get out of the tempdir
- cleanupWorkDir();
+ cleanupWorkTree();
print "ok\n";
new_parents="$new_parents $new_p"
;;
esac
+ else
+ new_parents="$new_parents $p"
fi
done
case $fast_forward in
}
elsif (/^Content-type:/i) {
$has_content_type = 1;
- if (/charset="?[^ "]+/) {
+ if (/charset="?([^ "]+)/) {
$body_encoding = $1;
}
push @xh, $_;
do
case "$1" in
-q|--quiet)
+ shift
quiet=1
;;
-i|--init)
break
;;
esac
- shift
done
git ls-files --stage -- "$@" | grep '^160000 ' |
return -1;
new_pack = parse_pack_index(sha1);
+ if (!new_pack)
+ return -1; /* parse_pack_index() already issued error message */
new_pack->next = repo->packs;
repo->packs = new_pack;
return 0;
off_t offset;
};
+struct base_data {
+ struct base_data *base;
+ struct base_data *child;
+ struct object_entry *obj;
+ void *data;
+ unsigned long size;
+};
+
/*
* Even if sizeof(union delta_base) == 24 on 64-bit archs, we really want
* to memcmp() only the first 20 bytes.
static struct object_entry *objects;
static struct delta_entry *deltas;
+static struct base_data *base_cache;
+static size_t base_cache_used;
static int nr_objects;
static int nr_deltas;
static int nr_resolved_deltas;
die("pack has bad object at offset %lu: %s", offset, buf);
}
+static void prune_base_data(struct base_data *retain)
+{
+ struct base_data *b = base_cache;
+ for (b = base_cache;
+ base_cache_used > delta_base_cache_limit && b;
+ b = b->child) {
+ if (b->data && b != retain) {
+ free(b->data);
+ b->data = NULL;
+ base_cache_used -= b->size;
+ }
+ }
+}
+
+static void link_base_data(struct base_data *base, struct base_data *c)
+{
+ if (base)
+ base->child = c;
+ else
+ base_cache = c;
+
+ c->base = base;
+ c->child = NULL;
+ base_cache_used += c->size;
+ prune_base_data(c);
+}
+
+static void unlink_base_data(struct base_data *c)
+{
+ struct base_data *base = c->base;
+ if (base)
+ base->child = NULL;
+ else
+ base_cache = NULL;
+ if (c->data) {
+ free(c->data);
+ base_cache_used -= c->size;
+ }
+}
+
static void *unpack_entry_data(unsigned long offset, unsigned long size)
{
z_stream stream;
}
}
-static void resolve_delta(struct object_entry *delta_obj, void *base_data,
- unsigned long base_size, enum object_type type)
+static void *get_base_data(struct base_data *c)
+{
+ if (!c->data) {
+ struct object_entry *obj = c->obj;
+
+ if (obj->type == OBJ_REF_DELTA || obj->type == OBJ_OFS_DELTA) {
+ void *base = get_base_data(c->base);
+ void *raw = get_data_from_pack(obj);
+ c->data = patch_delta(
+ base, c->base->size,
+ raw, obj->size,
+ &c->size);
+ free(raw);
+ if (!c->data)
+ bad_object(obj->idx.offset, "failed to apply delta");
+ } else
+ c->data = get_data_from_pack(obj);
+
+ base_cache_used += c->size;
+ prune_base_data(c);
+ }
+ return c->data;
+}
+
+static void resolve_delta(struct object_entry *delta_obj,
+ struct base_data *base_obj, enum object_type type)
{
void *delta_data;
unsigned long delta_size;
- void *result;
- unsigned long result_size;
union delta_base delta_base;
int j, first, last;
+ struct base_data result;
delta_obj->real_type = type;
delta_data = get_data_from_pack(delta_obj);
delta_size = delta_obj->size;
- result = patch_delta(base_data, base_size, delta_data, delta_size,
- &result_size);
+ result.data = patch_delta(get_base_data(base_obj), base_obj->size,
+ delta_data, delta_size,
+ &result.size);
free(delta_data);
- if (!result)
+ if (!result.data)
bad_object(delta_obj->idx.offset, "failed to apply delta");
- sha1_object(result, result_size, type, delta_obj->idx.sha1);
+ sha1_object(result.data, result.size, type, delta_obj->idx.sha1);
nr_resolved_deltas++;
+ result.obj = delta_obj;
+ link_base_data(base_obj, &result);
+
hashcpy(delta_base.sha1, delta_obj->idx.sha1);
if (!find_delta_children(&delta_base, &first, &last)) {
for (j = first; j <= last; j++) {
struct object_entry *child = objects + deltas[j].obj_no;
if (child->real_type == OBJ_REF_DELTA)
- resolve_delta(child, result, result_size, type);
+ resolve_delta(child, &result, type);
}
}
for (j = first; j <= last; j++) {
struct object_entry *child = objects + deltas[j].obj_no;
if (child->real_type == OBJ_OFS_DELTA)
- resolve_delta(child, result, result_size, type);
+ resolve_delta(child, &result, type);
}
}
- free(result);
+ unlink_base_data(&result);
}
static int compare_delta_entry(const void *a, const void *b)
{
int i;
struct delta_entry *delta = deltas;
- void *data;
struct stat st;
/*
nr_objects);
for (i = 0; i < nr_objects; i++) {
struct object_entry *obj = &objects[i];
- data = unpack_raw_entry(obj, &delta->base);
+ void *data = unpack_raw_entry(obj, &delta->base);
obj->real_type = obj->type;
if (obj->type == OBJ_REF_DELTA || obj->type == OBJ_OFS_DELTA) {
nr_deltas++;
struct object_entry *obj = &objects[i];
union delta_base base;
int j, ref, ref_first, ref_last, ofs, ofs_first, ofs_last;
+ struct base_data base_obj;
if (obj->type == OBJ_REF_DELTA || obj->type == OBJ_OFS_DELTA)
continue;
ofs = !find_delta_children(&base, &ofs_first, &ofs_last);
if (!ref && !ofs)
continue;
- data = get_data_from_pack(obj);
+ base_obj.data = get_data_from_pack(obj);
+ base_obj.size = obj->size;
+ base_obj.obj = obj;
+ link_base_data(NULL, &base_obj);
+
if (ref)
for (j = ref_first; j <= ref_last; j++) {
struct object_entry *child = objects + deltas[j].obj_no;
if (child->real_type == OBJ_REF_DELTA)
- resolve_delta(child, data,
- obj->size, obj->type);
+ resolve_delta(child, &base_obj, obj->type);
}
if (ofs)
for (j = ofs_first; j <= ofs_last; j++) {
struct object_entry *child = objects + deltas[j].obj_no;
if (child->real_type == OBJ_OFS_DELTA)
- resolve_delta(child, data,
- obj->size, obj->type);
+ resolve_delta(child, &base_obj, obj->type);
}
- free(data);
+ unlink_base_data(&base_obj);
display_progress(progress, nr_resolved_deltas);
}
}
return size;
}
-static void append_obj_to_pack(const unsigned char *sha1, void *buf,
+static struct object_entry *append_obj_to_pack(
+ const unsigned char *sha1, void *buf,
unsigned long size, enum object_type type)
{
struct object_entry *obj = &objects[nr_objects++];
write_or_die(output_fd, header, n);
obj[0].idx.crc32 = crc32(0, Z_NULL, 0);
obj[0].idx.crc32 = crc32(obj[0].idx.crc32, header, n);
+ obj[0].size = size;
+ obj[0].hdr_size = n;
+ obj[0].type = type;
+ obj[0].real_type = type;
obj[1].idx.offset = obj[0].idx.offset + n;
obj[1].idx.offset += write_compressed(output_fd, buf, size, &obj[0].idx.crc32);
hashcpy(obj->idx.sha1, sha1);
+ return obj;
}
static int delta_pos_compare(const void *_a, const void *_b)
for (i = 0; i < n; i++) {
struct delta_entry *d = sorted_by_pos[i];
- void *data;
- unsigned long size;
enum object_type type;
int j, first, last;
+ struct base_data base_obj;
if (objects[d->obj_no].real_type != OBJ_REF_DELTA)
continue;
- data = read_sha1_file(d->base.sha1, &type, &size);
- if (!data)
+ base_obj.data = read_sha1_file(d->base.sha1, &type, &base_obj.size);
+ if (!base_obj.data)
continue;
+ if (check_sha1_signature(d->base.sha1, base_obj.data,
+ base_obj.size, typename(type)))
+ die("local object %s is corrupt", sha1_to_hex(d->base.sha1));
+ base_obj.obj = append_obj_to_pack(d->base.sha1, base_obj.data,
+ base_obj.size, type);
+ link_base_data(NULL, &base_obj);
+
find_delta_children(&d->base, &first, &last);
for (j = first; j <= last; j++) {
struct object_entry *child = objects + deltas[j].obj_no;
if (child->real_type == OBJ_REF_DELTA)
- resolve_delta(child, data, size, type);
+ resolve_delta(child, &base_obj, type);
}
- if (check_sha1_signature(d->base.sha1, data, size, typename(type)))
- die("local object %s is corrupt", sha1_to_hex(d->base.sha1));
- append_obj_to_pack(d->base.sha1, data, size, type);
- free(data);
+ unlink_base_data(&base_obj);
display_progress(progress, nr_resolved_deltas);
}
free(sorted_by_pos);
*(unsigned long *)(opt->value) = approxidate(arg);
return 0;
}
+
+/*
+ * This should really be OPTION_FILENAME type as a part of
+ * parse_options that take prefix to do this while parsing.
+ */
+extern const char *parse_options_fix_filename(const char *prefix, const char *file)
+{
+ if (!file || !prefix || is_absolute_path(file) || !strcmp("-", file))
+ return file;
+ return prefix_filename(prefix, strlen(prefix), file);
+}
+
"use <n> digits to display SHA-1s", \
PARSE_OPT_OPTARG, &parse_opt_abbrev_cb, 0 }
+extern const char *parse_options_fix_filename(const char *prefix, const char *file);
+
#endif
int tweak = shared_repository;
if (!(mode & S_IWUSR))
tweak &= ~0222;
- mode = (mode & ~0777) | tweak;
+ mode |= tweak;
} else {
/* Preserve old PERM_UMASK behaviour */
if (mode & S_IWUSR)
#include "utf8.h"
#include "diff.h"
#include "revision.h"
+#include "path-list.h"
+#include "mailmap.h"
static char *user_format;
return out;
}
+static int mailmap_name(struct strbuf *sb, const char *email)
+{
+ static struct path_list *mail_map;
+ char buffer[1024];
+
+ if (!mail_map) {
+ mail_map = xcalloc(1, sizeof(*mail_map));
+ read_mailmap(mail_map, ".mailmap", NULL);
+ }
+
+ if (!mail_map->nr)
+ return -1;
+
+ if (!map_email(mail_map, email, buffer, sizeof(buffer)))
+ return -1;
+ strbuf_addstr(sb, buffer);
+ return 0;
+}
+
static size_t format_person_part(struct strbuf *sb, char part,
const char *msg, int len)
{
if (end >= len - 2)
goto skip;
- if (part == 'n') { /* name */
+ if (part == 'n' || part == 'N') { /* name */
while (end > 0 && isspace(msg[end - 1]))
end--;
- strbuf_add(sb, msg, end);
+ if (part != 'N' || !msg[end] || !msg[end + 1] ||
+ mailmap_name(sb, msg + end + 2) < 0)
+ strbuf_add(sb, msg, end);
return placeholder_len;
}
start = ++end; /* save email start position */
alias_all_urls();
}
+/*
+ * We need to make sure the tracking branches are well formed, but a
+ * wildcard refspec in "struct refspec" must have a trailing slash. We
+ * temporarily drop the trailing '/' while calling check_ref_format(),
+ * and put it back. The caller knows that a CHECK_REF_FORMAT_ONELEVEL
+ * error return is Ok for a wildcard refspec.
+ */
+static int verify_refname(char *name, int is_glob)
+{
+ int result, len = -1;
+
+ if (is_glob) {
+ len = strlen(name);
+ assert(name[len - 1] == '/');
+ name[len - 1] = '\0';
+ }
+ result = check_ref_format(name);
+ if (is_glob)
+ name[len - 1] = '/';
+ return result;
+}
+
static struct refspec *parse_refspec_internal(int nr_refspec, const char **refspec, int fetch, int verify)
{
int i;
struct refspec *rs = xcalloc(sizeof(*rs), nr_refspec);
for (i = 0; i < nr_refspec; i++) {
- size_t llen, rlen;
+ size_t llen;
int is_glob;
const char *lhs, *rhs;
- llen = rlen = is_glob = 0;
+ llen = is_glob = 0;
lhs = refspec[i];
if (*lhs == '+') {
}
if (rhs) {
- rhs++;
- rlen = strlen(rhs);
+ size_t rlen = strlen(++rhs);
is_glob = (2 <= rlen && !strcmp(rhs + rlen - 2, "/*"));
- if (is_glob)
- rlen -= 2;
- rs[i].dst = xstrndup(rhs, rlen);
+ rs[i].dst = xstrndup(rhs, rlen - is_glob);
}
llen = (rhs ? (rhs - lhs - 1) : strlen(lhs));
if ((rhs && !is_glob) || (!rhs && fetch))
goto invalid;
is_glob = 1;
- llen -= 2;
+ llen--;
} else if (rhs && is_glob) {
goto invalid;
}
if (!*rs[i].src)
; /* empty is ok */
else {
- st = check_ref_format(rs[i].src);
+ st = verify_refname(rs[i].src, is_glob);
if (st && st != CHECK_REF_FORMAT_ONELEVEL)
goto invalid;
}
} else if (!*rs[i].dst) {
; /* ok */
} else {
- st = check_ref_format(rs[i].dst);
+ st = verify_refname(rs[i].dst, is_glob);
if (st && st != CHECK_REF_FORMAT_ONELEVEL)
goto invalid;
}
if (!*rs[i].src)
; /* empty is ok */
else if (is_glob) {
- st = check_ref_format(rs[i].src);
+ st = verify_refname(rs[i].src, is_glob);
if (st && st != CHECK_REF_FORMAT_ONELEVEL)
goto invalid;
}
* - otherwise it must be a valid looking ref.
*/
if (!rs[i].dst) {
- st = check_ref_format(rs[i].src);
+ st = verify_refname(rs[i].src, is_glob);
if (st && st != CHECK_REF_FORMAT_ONELEVEL)
goto invalid;
} else if (!*rs[i].dst) {
goto invalid;
} else {
- st = check_ref_format(rs[i].dst);
+ st = verify_refname(rs[i].dst, is_glob);
if (st && st != CHECK_REF_FORMAT_ONELEVEL)
goto invalid;
}
if (!fetch->dst)
continue;
if (fetch->pattern) {
- if (!prefixcmp(needle, key) &&
- needle[strlen(key)] == '/') {
+ if (!prefixcmp(needle, key)) {
*result = xmalloc(strlen(value) +
strlen(needle) -
strlen(key) + 1);
continue;
}
- if (rs[i].pattern &&
- !prefixcmp(src->name, rs[i].src) &&
- src->name[strlen(rs[i].src)] == '/')
+ if (rs[i].pattern && !prefixcmp(src->name, rs[i].src))
return rs + i;
}
if (matching_refs != -1)
static void file_add_remove(struct diff_options *options,
int addremove, unsigned mode,
const unsigned char *sha1,
- const char *base, const char *path)
+ const char *fullpath)
{
int diff = REV_TREE_DIFFERENT;
unsigned old_mode, unsigned new_mode,
const unsigned char *old_sha1,
const unsigned char *new_sha1,
- const char *base, const char *path)
+ const char *fullpath)
{
tree_difference = REV_TREE_DIFFERENT;
DIFF_OPT_SET(options, HAS_CHANGES);
#define CHILD_SHOWN (1u<<6)
#define ADDED (1u<<7) /* Parents already parsed and added? */
#define SYMMETRIC_LEFT (1u<<8)
-#define TOPOSORT (1u<<9) /* In the active toposort list.. */
struct rev_info;
struct log_info;
off_t base_offset;
base_offset = get_delta_base(p, w_curs, &curpos, *type, obj_offset);
+ unuse_pack(w_curs);
base = cache_or_unpack_entry(p, base_offset, &base_size, type, 0);
if (!base)
die("failed to read delta base object"
test_cmp again/empty again/err2
'
+test_expect_success 'init with --template' '
+ mkdir template-source &&
+ echo content >template-source/file &&
+ (
+ mkdir template-custom &&
+ cd template-custom &&
+ git init --template=../template-source
+ ) &&
+ test_cmp template-source/file template-custom/.git/file
+'
+
+test_expect_success 'init with --template (blank)' '
+ (
+ mkdir template-plain &&
+ cd template-plain &&
+ git init
+ ) &&
+ test -f template-plain/.git/info/exclude &&
+ (
+ mkdir template-blank &&
+ cd template-blank &&
+ git init --template=
+ ) &&
+ ! test -f template-blank/.git/info/exclude
+'
+
test_done
>file &&
git add file &&
+ test_tick &&
git commit -m initial &&
echo >file &&
git add file
test_expect_success 'write-tree should notice unwritable repository' '
(
- chmod a-w .git/objects
+ chmod a-w .git/objects .git/objects/?? &&
test_must_fail git write-tree
)
status=$?
- chmod 775 .git/objects
+ chmod 775 .git/objects .git/objects/??
(exit $status)
'
test_expect_success 'commit should notice unwritable repository' '
(
- chmod a-w .git/objects
+ chmod a-w .git/objects .git/objects/?? &&
test_must_fail git commit -m second
)
status=$?
- chmod 775 .git/objects
+ chmod 775 .git/objects .git/objects/??
(exit $status)
'
test_expect_success 'update-index should notice unwritable repository' '
(
- echo a >file &&
- chmod a-w .git/objects
+ echo 6O >file &&
+ chmod a-w .git/objects .git/objects/?? &&
test_must_fail git update-index file
)
status=$?
- chmod 775 .git/objects
+ chmod 775 .git/objects .git/objects/??
(exit $status)
'
(
echo b >file &&
- chmod a-w .git/objects
+ chmod a-w .git/objects .git/objects/?? &&
test_must_fail git add file
)
status=$?
- chmod 775 .git/objects
+ chmod 775 .git/objects .git/objects/??
(exit $status)
'
test $ret != "0"
'
+for u in 002 022
+do
+ test_expect_success "shared=1 does not clear bits preset by umask $u" '
+ mkdir sub && (
+ cd sub &&
+ umask $u &&
+ git init --shared=1 &&
+ test 1 = "$(git config core.sharedrepository)"
+ ) &&
+ actual=$(ls -l sub/.git/HEAD)
+ case "$actual" in
+ -rw-rw-r--*)
+ : happy
+ ;;
+ *)
+ echo Oops, .git/HEAD is not 0664 but $actual
+ false
+ ;;
+ esac
+ '
+ rm -rf sub
+done
+
test_expect_success 'shared=all' '
mkdir sub &&
cd sub &&
--- /dev/null
+#!/bin/sh
+
+test_description='update-index with options'
+
+. ./test-lib.sh
+
+test_expect_success basics '
+ >one &&
+ >two &&
+ >three &&
+
+ # need --add when adding
+ test_must_fail git update-index one &&
+ test -z "$(git ls-files)" &&
+ git update-index --add one &&
+ test zone = "z$(git ls-files)" &&
+
+ # update-index is atomic
+ echo 1 >one &&
+ test_must_fail git update-index one two &&
+ echo "M one" >expect &&
+ git diff-files --name-status >actual &&
+ test_cmp expect actual &&
+
+ git update-index --add one two three &&
+ for i in one three two; do echo $i; done >expect &&
+ git ls-files >actual &&
+ test_cmp expect actual &&
+
+ test_tick &&
+ (
+ test_create_repo xyzzy &&
+ cd xyzzy &&
+ >file &&
+ git add file
+ git commit -m "sub initial"
+ ) &&
+ git add xyzzy &&
+
+ test_tick &&
+ git commit -m initial &&
+ git tag initial
+'
+
+test_expect_success '--ignore-missing --refresh' '
+ git reset --hard initial &&
+ echo 2 >one &&
+ test_must_fail git update-index --refresh &&
+ echo 1 >one &&
+ git update-index --refresh &&
+ rm -f two &&
+ test_must_fail git update-index --refresh &&
+ git update-index --ignore-missing --refresh
+
+'
+
+test_expect_success '--unmerged --refresh' '
+ git reset --hard initial &&
+ info=$(git ls-files -s one | sed -e "s/ 0 / 1 /") &&
+ git rm --cached one &&
+ echo "$info" | git update-index --index-info &&
+ test_must_fail git update-index --refresh &&
+ git update-index --unmerged --refresh &&
+ echo 2 >two &&
+ test_must_fail git update-index --unmerged --refresh >actual &&
+ grep two actual &&
+ ! grep one actual &&
+ ! grep three actual
+'
+
+test_expect_success '--ignore-submodules --refresh (1)' '
+ git reset --hard initial &&
+ rm -f two &&
+ test_must_fail git update-index --ignore-submodules --refresh
+'
+
+test_expect_success '--ignore-submodules --refresh (2)' '
+ git reset --hard initial &&
+ test_tick &&
+ (
+ cd xyzzy &&
+ git commit -m "sub second" --allow-empty
+ ) &&
+ test_must_fail git update-index --refresh &&
+ test_must_fail git update-index --ignore-missing --refresh &&
+ git update-index --ignore-submodules --refresh
+'
+
+test_done
--- /dev/null
+#!/bin/sh
+
+test_description='test show-branch with more than 8 heads'
+
+. ./test-lib.sh
+
+numbers="1 2 3 4 5 6 7 8 9 10"
+
+test_expect_success 'setup' '
+
+ > file &&
+ git add file &&
+ test_tick &&
+ git commit -m initial &&
+
+ for i in $numbers
+ do
+ git checkout -b branch$i master &&
+ > file$i &&
+ git add file$i &&
+ test_tick &&
+ git commit -m branch$i || break
+ done
+
+'
+
+cat > expect << EOF
+! [branch1] branch1
+ ! [branch2] branch2
+ ! [branch3] branch3
+ ! [branch4] branch4
+ ! [branch5] branch5
+ ! [branch6] branch6
+ ! [branch7] branch7
+ ! [branch8] branch8
+ ! [branch9] branch9
+ * [branch10] branch10
+----------
+ * [branch10] branch10
+ + [branch9] branch9
+ + [branch8] branch8
+ + [branch7] branch7
+ + [branch6] branch6
+ + [branch5] branch5
+ + [branch4] branch4
+ + [branch3] branch3
+ + [branch2] branch2
++ [branch1] branch1
++++++++++* [branch10^] initial
+EOF
+
+test_expect_success 'show-branch with more than 8 branches' '
+
+ git show-branch $(for i in $numbers; do echo branch$i; done) > out &&
+ test_cmp expect out
+
+'
+
+test_done
! git rm nonexistent
'
+test_expect_success 'Call "rm" from outside the work tree' '
+ mkdir repo &&
+ cd repo &&
+ git init &&
+ echo something > somefile &&
+ git add somefile &&
+ git commit -m "add a file" &&
+ (cd .. &&
+ git --git-dir=repo/.git --work-tree=repo rm somefile) &&
+ test_must_fail git ls-files --error-unmatch somefile
+'
+
test_done
-test_done
\ No newline at end of file
+test_done
+
'
. ./test-lib.sh
-TAR=${TAR:-tar}
UNZIP=${UNZIP:-unzip}
SUBSTFORMAT=%H%n
test_expect_success \
'validate file modification time' \
'mkdir extract &&
- $TAR xf b.tar -C extract a/a &&
+ "$TAR" xf b.tar -C extract a/a &&
perl -e '\''print((stat("extract/a/a"))[9], "\n")'\'' >b.mtime &&
echo "1117231200" >expected.mtime &&
diff expected.mtime b.mtime'
test_expect_success \
'extract tar archive' \
- '(cd b && $TAR xf -) <b.tar'
+ '(cd b && "$TAR" xf -) <b.tar'
test_expect_success \
'validate filenames' \
test_expect_success \
'extract tar archive with prefix' \
- '(cd c && $TAR xf -) <c.tar'
+ '(cd c && "$TAR" xf -) <c.tar'
test_expect_success \
'validate filenames with prefix' \
test_expect_success \
'extract substfiles' \
- '(mkdir f && cd f && $TAR xf -) <f.tar'
+ '(mkdir f && cd f && "$TAR" xf -) <f.tar'
test_expect_success \
'validate substfile contents' \
test_expect_success \
'extract substfiles from archive with prefix' \
- '(mkdir g && cd g && $TAR xf -) <g.tar'
+ '(mkdir g && cd g && "$TAR" xf -) <g.tar'
test_expect_success \
'validate substfile contents from archive with prefix' \
'git mailsplit -o. ../t5100/sample.mbox >last &&
last=`cat last` &&
echo total is $last &&
- test `cat last` = 9'
+ test `cat last` = 10'
for mail in `echo 00*`
do
--- /dev/null
+From b9704a518e21158433baa2cc2d591fea687967f6 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Lukas=20Sandstr=C3=B6m?= <lukass@etek.chalmers.se>
+Date: Thu, 10 Jul 2008 23:41:33 +0200
+Subject: Re: discussion that lead to this patch
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+[PATCH] git-mailinfo: Fix getting the subject from the body
+
+"Subject: " isn't in the static array "header", and thus
+memcmp("Subject: ", header[i], 7) will never match.
+
+Signed-off-by: Lukas Sandström <lukass@etek.chalmers.se>
+Signed-off-by: Junio C Hamano <gitster@pobox.com>
+---
+ builtin-mailinfo.c | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
+index 962aa34..2d1520f 100644
+--- a/builtin-mailinfo.c
++++ b/builtin-mailinfo.c
+@@ -334,7 +334,7 @@ static int check_header(char *line, unsigned linesize, char **hdr_data, int over
+ return 1;
+ if (!memcmp("[PATCH]", line, 7) && isspace(line[7])) {
+ for (i = 0; header[i]; i++) {
+- if (!memcmp("Subject: ", header[i], 9)) {
++ if (!memcmp("Subject", header[i], 7)) {
+ if (! handle_header(line, hdr_data[i], 0)) {
+ return 1;
+ }
+--
+1.5.6.2.455.g1efb2
+
--- /dev/null
+Author: Lukas Sandström
+Email: lukass@etek.chalmers.se
+Subject: git-mailinfo: Fix getting the subject from the body
+Date: Thu, 10 Jul 2008 23:41:33 +0200
+
--- /dev/null
+"Subject: " isn't in the static array "header", and thus
+memcmp("Subject: ", header[i], 7) will never match.
+
+Signed-off-by: Lukas Sandström <lukass@etek.chalmers.se>
+Signed-off-by: Junio C Hamano <gitster@pobox.com>
--- /dev/null
+---
+ builtin-mailinfo.c | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
+index 962aa34..2d1520f 100644
+--- a/builtin-mailinfo.c
++++ b/builtin-mailinfo.c
+@@ -334,7 +334,7 @@ static int check_header(char *line, unsigned linesize, char **hdr_data, int over
+ return 1;
+ if (!memcmp("[PATCH]", line, 7) && isspace(line[7])) {
+ for (i = 0; header[i]; i++) {
+- if (!memcmp("Subject: ", header[i], 9)) {
++ if (!memcmp("Subject", header[i], 7)) {
+ if (! handle_header(line, hdr_data[i], 0)) {
+ return 1;
+ }
+--
+1.5.6.2.455.g1efb2
+
=20
=20
2. When the environment variable 'GIT_EXTERNAL_DIFF' is set, the
+From b9704a518e21158433baa2cc2d591fea687967f6 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Lukas=20Sandstr=C3=B6m?= <lukass@etek.chalmers.se>
+Date: Thu, 10 Jul 2008 23:41:33 +0200
+Subject: Re: discussion that lead to this patch
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+[PATCH] git-mailinfo: Fix getting the subject from the body
+
+"Subject: " isn't in the static array "header", and thus
+memcmp("Subject: ", header[i], 7) will never match.
+
+Signed-off-by: Lukas Sandström <lukass@etek.chalmers.se>
+Signed-off-by: Junio C Hamano <gitster@pobox.com>
+---
+ builtin-mailinfo.c | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
+index 962aa34..2d1520f 100644
+--- a/builtin-mailinfo.c
++++ b/builtin-mailinfo.c
+@@ -334,7 +334,7 @@ static int check_header(char *line, unsigned linesize, char **hdr_data, int over
+ return 1;
+ if (!memcmp("[PATCH]", line, 7) && isspace(line[7])) {
+ for (i = 0; header[i]; i++) {
+- if (!memcmp("Subject: ", header[i], 9)) {
++ if (!memcmp("Subject", header[i], 7)) {
+ if (! handle_header(line, hdr_data[i], 0)) {
+ return 1;
+ }
+--
+1.5.6.2.455.g1efb2
+
--- /dev/null
+#!/bin/sh
+
+test_description='fetch follows remote tracking branches correctly'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+ >file &&
+ git add . &&
+ test_tick &&
+ git commit -m Initial &&
+ git branch b-0 &&
+ git branch b1 &&
+ git branch b/one &&
+ test_create_repo other &&
+ (
+ cd other &&
+ git config remote.origin.url .. &&
+ git config remote.origin.fetch "+refs/heads/b/*:refs/remotes/b/*"
+ )
+'
+
+test_expect_success fetch '
+ (
+ cd other && git fetch origin &&
+ test "$(git for-each-ref --format="%(refname)")" = refs/remotes/b/one
+ )
+'
+
+test_done
--- /dev/null
+#!/bin/sh
+
+test_description=clone
+
+. ./test-lib.sh
+
+test_expect_success setup '
+ echo "#!/bin/sh" > not_ssh
+ echo "echo \"\$*\" > not_ssh_output" >> not_ssh
+ echo "exit 1" >> not_ssh
+ chmod +x not_ssh
+'
+
+test_expect_success 'clone calls git-upload-pack unqualified with no -u option' '
+ GIT_SSH=./not_ssh git clone localhost:/path/to/repo junk
+ echo "localhost git-upload-pack '\''/path/to/repo'\''" >expected
+ test_cmp expected not_ssh_output
+'
+
+test_expect_success 'clone calls specified git-upload-pack with -u option' '
+ GIT_SSH=./not_ssh git clone -u /something/bin/git-upload-pack localhost:/path/to/repo junk
+ echo "localhost /something/bin/git-upload-pack '\''/path/to/repo'\''" >expected
+ test_cmp expected not_ssh_output
+'
+
+test_done
test_cmp expect actual
'
+test_expect_success 'filename for the message is relative to cwd' '
+ mkdir subdir &&
+ echo "Tag message in top directory" >msgfile-5 &&
+ echo "Tag message in sub directory" >subdir/msgfile-5 &&
+ (
+ cd subdir &&
+ git tag -a -F msgfile-5 tag-from-subdir
+ ) &&
+ git cat-file tag tag-from-subdir | grep "in sub directory"
+'
+
+test_expect_success 'filename for the message is relative to cwd' '
+ echo "Tag message in sub directory" >subdir/msgfile-6 &&
+ (
+ cd subdir &&
+ git tag -a -F msgfile-6 tag-from-subdir-2
+ ) &&
+ git cat-file tag tag-from-subdir-2 | grep "in sub directory"
+'
+
test_done
diff expect output
'
+test_expect_success 'commit message from file (1)' '
+ mkdir subdir &&
+ echo "Log in top directory" >log &&
+ echo "Log in sub directory" >subdir/log &&
+ (
+ cd subdir &&
+ git commit --allow-empty -F log
+ ) &&
+ commit_msg_is "Log in sub directory"
+'
+
+test_expect_success 'commit message from file (2)' '
+ rm -f log &&
+ echo "Log in sub directory" >subdir/log &&
+ (
+ cd subdir &&
+ git commit --allow-empty -F log
+ ) &&
+ commit_msg_is "Log in sub directory"
+'
+
+test_expect_success 'commit message from stdin' '
+ (
+ cd subdir &&
+ echo "Log with foo word" | git commit --allow-empty -F -
+ ) &&
+ commit_msg_is "Log with foo word"
+'
+
test_done
test_debug 'gitk --all'
test_expect_success 'test option parsing' '
- if git merge -$ c1
- then
- echo "[OOPS] -$ accepted"
- false
- fi &&
- if git merge --no-such c1
- then
- echo "[OOPS] --no-such accepted"
- false
- fi &&
- if git merge -s foobar c1
- then
- echo "[OOPS] -s foobar accepted"
- false
- fi &&
- if git merge -s=foobar c1
- then
- echo "[OOPS] -s=foobar accepted"
- false
- fi &&
- if git merge -m
- then
- echo "[OOPS] missing commit msg accepted"
- false
- fi &&
- if git merge
- then
- echo "[OOPS] missing commit references accepted"
- false
- fi
+ test_must_fail git merge -$ c1 &&
+ test_must_fail git merge --no-such c1 &&
+ test_must_fail git merge -s foobar c1 &&
+ test_must_fail git merge -s=foobar c1 &&
+ test_must_fail git merge -m &&
+ test_must_fail git merge
'
test_expect_success 'merge c0 with c1' '
run_active_slot(slot);
if (results.curl_result != CURLE_OK) {
strbuf_release(&buffer);
- if (missing_target(&results)) {
- return NULL;
- } else {
- error("%s", curl_errorstr);
- return NULL;
- }
+ if (missing_target(&results))
+ die("%s not found: did you run git update-server-info on the server?", refs_url);
+ else
+ die("%s download error - %s", refs_url, curl_errorstr);
}
} else {
strbuf_release(&buffer);
- error("Unable to start request");
- return NULL;
+ die("Unable to start HTTP request");
}
data = buffer.buf;
return newbase;
}
+static char *malloc_fullname(const char *base, int baselen, const char *path, int pathlen)
+{
+ char *fullname = xmalloc(baselen + pathlen + 1);
+ memcpy(fullname, base, baselen);
+ memcpy(fullname + baselen, path, pathlen);
+ fullname[baselen + pathlen] = 0;
+ return fullname;
+}
+
static void show_entry(struct diff_options *opt, const char *prefix, struct tree_desc *desc,
const char *base, int baselen);
const char *path1, *path2;
const unsigned char *sha1, *sha2;
int cmp, pathlen1, pathlen2;
+ char *fullname;
sha1 = tree_entry_extract(t1, &path1, &mode1);
sha2 = tree_entry_extract(t2, &path2, &mode2);
if (DIFF_OPT_TST(opt, RECURSIVE) && S_ISDIR(mode1)) {
int retval;
char *newbase = malloc_base(base, baselen, path1, pathlen1);
- if (DIFF_OPT_TST(opt, TREE_IN_RECURSIVE))
+ if (DIFF_OPT_TST(opt, TREE_IN_RECURSIVE)) {
+ newbase[baselen + pathlen1] = 0;
opt->change(opt, mode1, mode2,
- sha1, sha2, base, path1);
+ sha1, sha2, newbase);
+ newbase[baselen + pathlen1] = '/';
+ }
retval = diff_tree_sha1(sha1, sha2, newbase, opt);
free(newbase);
return retval;
}
- opt->change(opt, mode1, mode2, sha1, sha2, base, path1);
+ fullname = malloc_fullname(base, baselen, path1, pathlen1);
+ opt->change(opt, mode1, mode2, sha1, sha2, fullname);
+ free(fullname);
return 0;
}
unsigned mode;
const char *path;
const unsigned char *sha1 = tree_entry_extract(desc, &path, &mode);
+ int pathlen = tree_entry_len(path, sha1);
if (DIFF_OPT_TST(opt, RECURSIVE) && S_ISDIR(mode)) {
enum object_type type;
- int pathlen = tree_entry_len(path, sha1);
char *newbase = malloc_base(base, baselen, path, pathlen);
struct tree_desc inner;
void *tree;
free(tree);
free(newbase);
} else {
- opt->add_remove(opt, prefix[0], mode, sha1, base, path);
+ char *fullname = malloc_fullname(base, baselen, path, pathlen);
+ opt->add_remove(opt, prefix[0], mode, sha1, fullname);
+ free(fullname);
}
}