Lukas Sandström <lukass@etek.chalmers.se>
Martin Langhoff <martin@catalyst.net.nz>
Michael Coleman <tutufan@gmail.com>
+Michael J Gruber <git@drmicha.warpmail.net> <michaeljgruber+gmane@fastmail.fm>
Michael W. Olson <mwolson@gnu.org>
Michele Ballabio <barra_cuda@katamail.com>
Nanako Shiraishi <nanako3@bluebottle.com>
-Git v1.7.0.3 Release Notes (draft)
-==================================
+Git v1.7.0.3 Release Notes
+==========================
Fixes since v1.7.0.2
--------------------
* "git add -i" didn't handle a deleted path very well.
+ * "git blame" padded line numbers with one extra SP when the total number
+ of lines was one less than multiple of ten due to an off-by-one error.
+
* "git fetch --all/--multi" used to discard information for remotes that
are fetched earlier.
or are written by "me", instead of the ones that have "it" _and_ are
written by "me".
+ * "git log -g branch" misbehaved when there was no entries in the reflog
+ for the named branch.
+
* "git mailinfo" (hence "git am") incorrectly removed initial indent from
paragraphs.
matching branch.<name>.remote.
And other minor fixes and documentation updates.
-
---
-exec >/var/tmp/1
-echo O=$(git describe)
-O=v1.7.0.2-53-g6eb3adf
-git shortlog --no-merges $O..
--- /dev/null
+Git v1.7.0.4 Release Notes
+==========================
+
+Fixes since v1.7.0.3
+--------------------
+
+ * Optimized ntohl/htonl on big-endian machines were broken.
+
+ * Color values given to "color.<cmd>.<slot>" configuration can now have
+ more than one attributes (e.g. "bold ul").
+
+ * "git add -u nonexistent-path" did not complain.
+
+ * "git apply --whitespace=fix" didn't work well when an early patch in
+ a patch series adds trailing blank lines and a later one depended on
+ such a block of blank lines at the end.
+
+ * "git fast-export" didn't check error status and stop when marks file
+ cannot be opened.
+
+ * "git format-patch --ignore-if-in-upstream" gave unwarranted errors
+ when the range was empty, instead of silently finishing.
+
+ * "git remote prune" did not detect remote tracking refs that became
+ dangling correctly.
+
+And other minor fixes and documentation updates.
out of sync with the index and working tree. If set to "warn",
print a warning of such a push to stderr, but allow the push to
proceed. If set to false or "ignore", allow such pushes with no
- message. Defaults to "warn".
+ message. Defaults to "refuse".
receive.denyNonFastForwards::
If set to true, git-receive-pack will deny a ref update which is
Create the branch's reflog. This activates recording of
all changes made to the branch ref, enabling use of date
based sha1 expressions such as "<branchname>@\{yesterday}".
+ Note that in non-bare repositories, reflogs are usually
+ enabled by default by the `core.logallrefupdates` config option.
-f::
--force::
Examples
--------
-Clone from upstream::
+* Clone from upstream:
+
------------
$ git clone git://git.kernel.org/pub/scm/.../linux-2.6 my2.6
------------
-Make a local clone that borrows from the current directory, without checking things out::
+* Make a local clone that borrows from the current directory, without checking things out:
+
------------
$ git clone -l -s -n . ../copy
------------
-Clone from upstream while borrowing from an existing local directory::
+* Clone from upstream while borrowing from an existing local directory:
+
------------
$ git clone --reference my2.6 \
------------
-Create a bare repository to publish your changes to the public::
+* Create a bare repository to publish your changes to the public:
+
------------
$ git clone --bare -l /home/proj/.git /pub/scm/proj.git
------------
-Create a repository on the kernel.org machine that borrows from Linus::
+* Create a repository on the kernel.org machine that borrows from Linus:
+
------------
$ git clone --bare -l -s /pub/scm/.../torvalds/linux-2.6.git \
of commits which would be displayed by "git log v1.0.4..parent".
The hash suffix is "-g" + 7-char abbreviation for the tip commit
of parent (which was `2414721b194453f058079d897d13c4e377f92dc6`).
+The "g" prefix stands for "git" and is used to allow describing the version of
+a software depending on the SCM the software is managed with. This is useful
+in an environment where people may use different SCMs.
Doing a 'git describe' on a tag-name will just show the tag name:
SYNOPSIS
--------
-'git fetch' <options> <repository> <refspec>...
+'git fetch' [<options>] [<repository> [<refspec>...]]
-'git fetch' <options> <group>
+'git fetch' [<options>] <group>
-'git fetch' --multiple <options> [<repository> | <group>]...
+'git fetch' --multiple [<options>] [<repository> | <group>]...
-'git fetch' --all <options>
+'git fetch' --all [<options>]
DESCRIPTION
configuration file:
http.getanyfile::
- This serves older Git clients which are unable to use the
+ This serves Git clients older than version 1.6.6 that are unable to use the
upload pack service. When enabled, clients are able to read
any file within the repository, including objects that are
no longer reachable from a branch but are still present.
[verse]
'git push' [--all | --mirror | --tags] [-n | --dry-run] [--receive-pack=<git-receive-pack>]
[--repo=<repository>] [-f | --force] [-v | --verbose] [-u | --set-upstream]
- [<repository> <refspec>...]
+ [<repository> [<refspec>...]]
DESCRIPTION
-----------
~~~~~~~~~~~~~~~~~
If only 1 tree is specified, 'git read-tree' operates as if the user did not
specify `-m`, except that if the original index has an entry for a
-given pathname, and the contents of the path matches with the tree
+given pathname, and the contents of the path match with the tree
being read, the stat info from the index is used. (In other words, the
index's stat()s take precedence over the merged tree's).
the following:
1. The current index and work tree is derived from $H, but
- the user may have local changes in them since $H;
+ the user may have local changes in them since $H.
2. The user wants to fast-forward to $M.
In this case, the `git read-tree -m $H $M` command makes sure
that no local change is lost as the result of this "merge".
-Here are the "carry forward" rules:
+Here are the "carry forward" rules, where "I" denotes the index,
+"clean" means that index and work tree coincide, and "exists"/"nothing"
+refer to the presence of a path in the specified commit:
- I (index) H M Result
+ I H M Result
-------------------------------------------------------
- 0 nothing nothing nothing (does not happen)
- 1 nothing nothing exists use M
- 2 nothing exists nothing remove path from index
- 3 nothing exists exists, use M if "initial checkout"
+ 0 nothing nothing nothing (does not happen)
+ 1 nothing nothing exists use M
+ 2 nothing exists nothing remove path from index
+ 3 nothing exists exists, use M if "initial checkout",
H == M keep index otherwise
- exists fail
+ exists, fail
H != M
clean I==H I==M
------------------
- 4 yes N/A N/A nothing nothing keep index
- 5 no N/A N/A nothing nothing keep index
+ 4 yes N/A N/A nothing nothing keep index
+ 5 no N/A N/A nothing nothing keep index
- 6 yes N/A yes nothing exists keep index
- 7 no N/A yes nothing exists keep index
- 8 yes N/A no nothing exists fail
- 9 no N/A no nothing exists fail
+ 6 yes N/A yes nothing exists keep index
+ 7 no N/A yes nothing exists keep index
+ 8 yes N/A no nothing exists fail
+ 9 no N/A no nothing exists fail
10 yes yes N/A exists nothing remove path from index
11 no yes N/A exists nothing fail
12 yes no N/A exists nothing fail
13 no no N/A exists nothing fail
- clean (H=M)
+ clean (H==M)
------
14 yes exists exists keep index
15 no exists exists keep index
21 no yes no exists exists fail
In all "keep index" cases, the index entry stays as in the
-original index file. If the entry were not up to date,
+original index file. If the entry is not up to date,
'git read-tree' keeps the copy in the work tree intact when
operating under the -u flag.
When this form of 'git read-tree' returns successfully, you can
-see what "local changes" you made are carried forward by running
+see which of the "local changes" that you made were carried forward by running
`git diff-index --cached $M`. Note that this does not
-necessarily match `git diff-index --cached $H` would have
+necessarily match what `git diff-index --cached $H` would have
produced before such a two tree merge. This is because of cases
18 and 19 --- if you already had the changes in $M (e.g. maybe
you picked it up via e-mail in a patch form), `git diff-index
--cached $H` would have told you about the change before this
merge, but it would not show in `git diff-index --cached $M`
-output after two-tree merge.
+output after the two-tree merge.
-Case #3 is slightly tricky and needs explanation. The result from this
+Case 3 is slightly tricky and needs explanation. The result from this
rule logically should be to remove the path if the user staged the removal
of the path and then switching to a new branch. That however will prevent
the initial checkout from happening, so the rule is modified to use M (new
-tree) only when the contents of the index is empty. Otherwise the removal
+tree) only when the content of the index is empty. Otherwise the removal
of the path is kept as long as $H and $M are the same.
3-Way Merge
[verse]
'git reflog expire' [--dry-run] [--stale-fix] [--verbose]
[--expire=<time>] [--expire-unreachable=<time>] [--all] <refs>...
-+
'git reflog delete' ref@\{specifier\}...
-+
'git reflog' ['show'] [log-options] [<ref>]
Reflog is a mechanism to record when the tip of branches are
[verse]
'git show-ref' [-q|--quiet] [--verify] [--head] [-d|--dereference]
[-s|--hash[=<n>]] [--abbrev[=<n>]] [--tags]
- [--heads] [--] <pattern>...
+ [--heads] [--] [<pattern>...]
'git show-ref' --exclude-existing[=<pattern>] < ref-list
DESCRIPTION
branch of the `git.git` repository.
Documentation for older releases are available here:
-* link:v1.7.0.2/git.html[documentation for release 1.7.0.2]
+* link:v1.7.0.4/git.html[documentation for release 1.7.0.4]
* release notes for
+ link:RelNotes-1.7.0.4.txt[1.7.0.4],
+ link:RelNotes-1.7.0.3.txt[1.7.0.3],
link:RelNotes-1.7.0.2.txt[1.7.0.2],
link:RelNotes-1.7.0.1.txt[1.7.0.1],
link:RelNotes-1.7.0.txt[1.7.0].
NAME
----
-gitdiffcore - Tweaking diff output (June 2005)
+gitdiffcore - Tweaking diff output
SYNOPSIS
--------
The Git transport starts off by sending the command and repository
on the wire using the pkt-line format, followed by a NUL byte and a
-hostname paramater, terminated by a NUL byte.
+hostname parameter, terminated by a NUL byte.
0032git-upload-pack /project.git\0host=myserver.com\0
C: 0009done\n
- S: 003aACK 74730d410fcb6603ace96f1dc55ea6196122532d\n
+ S: 0031ACK 74730d410fcb6603ace96f1dc55ea6196122532d\n
S: [PACKFILE]
----
C: 0000
C: [PACKDATA]
- S: 000aunpack ok\n
- S: 0014ok refs/heads/debug\n
- S: 0026ng refs/heads/master non-fast-forward\n
+ S: 000eunpack ok\n
+ S: 0018ok refs/heads/debug\n
+ S: 002ang refs/heads/master non-fast-forward\n
----
One of the following notations can be used
to name the remote repository:
-===============================================================
- rsync://host.xz/path/to/repo.git/
- http://host.xz{startsb}:port{endsb}/path/to/repo.git/
- https://host.xz{startsb}:port{endsb}/path/to/repo.git/
- ssh://{startsb}user@{endsb}host.xz/path/to/repo.git/
- ssh://{startsb}user@{endsb}host.xz/~user/path/to/repo.git/
- ssh://{startsb}user@{endsb}host.xz/~/path/to/repo.git
-===============================================================
SSH is the default transport protocol over the network. You can
optionally specify which user to log-in as, and an alternate,
only the former supports port specification. The following
three are identical to the last three above, respectively:
-===============================================================
- {startsb}user@{endsb}host.xz:/path/to/repo.git/
- {startsb}user@{endsb}host.xz:~user/path/to/repo.git/
- {startsb}user@{endsb}host.xz:path/to/repo.git
-===============================================================
To sync with a local directory, you can use:
-===============================================================
- /path/to/repo.git/
- file:///path/to/repo.git/
-===============================================================
ifndef::git-clone[]
They are mostly equivalent, except when cloning. See
#!/bin/sh
GVF=GIT-VERSION-FILE
-DEF_VER=v1.7.0.2
+DEF_VER=v1.7.0.4
LF='
'
SCRIPT_SH =
TEST_PROGRAMS =
+# Having this variable in your environment would break pipelines because
+# you cause "cd" to echo its destination to stdout. It can also take
+# scripts to unexpected places. If you like CDPATH, define it for your
+# interactive shell sessions without exporting it.
+unexport CDPATH
+
SCRIPT_SH += git-am.sh
SCRIPT_SH += git-bisect.sh
SCRIPT_SH += git-difftool--helper.sh
SNPRINTF_RETURNS_BOGUS = YesPlease
SHELL_PATH = /usr/gnu/bin/bash
NEEDS_LIBGEN = YesPlease
+ NEEDS_LIBICONV = YesPlease
endif
ifeq ($(uname_S),IRIX64)
NO_SETENV=YesPlease
SNPRINTF_RETURNS_BOGUS = YesPlease
SHELL_PATH=/usr/gnu/bin/bash
NEEDS_LIBGEN = YesPlease
+ NEEDS_LIBICONV = YesPlease
endif
ifeq ($(uname_S),HP-UX)
NO_IPV6=YesPlease
-Documentation/RelNotes-1.7.0.3.txt
\ No newline at end of file
+Documentation/RelNotes-1.7.0.4.txt
\ No newline at end of file
}
}
-static void prune_directory(struct dir_struct *dir, const char **pathspec, int prefix)
+static char *find_used_pathspec(const char **pathspec)
+{
+ char *seen;
+ int i;
+
+ for (i = 0; pathspec[i]; i++)
+ ; /* just counting */
+ seen = xcalloc(i, 1);
+ fill_pathspec_matches(pathspec, seen, i);
+ return seen;
+}
+
+static char *prune_directory(struct dir_struct *dir, const char **pathspec, int prefix)
{
char *seen;
int i, specs;
}
dir->nr = dst - dir->entries;
fill_pathspec_matches(pathspec, seen, specs);
-
- for (i = 0; i < specs; i++) {
- if (!seen[i] && pathspec[i][0] && !file_exists(pathspec[i]))
- die("pathspec '%s' did not match any files",
- pathspec[i]);
- }
- free(seen);
+ return seen;
}
static void treat_gitlinks(const char **pathspec)
int flags;
int add_new_files;
int require_pathspec;
+ char *seen = NULL;
git_config(add_config, NULL);
/* This picks up the paths that are not tracked */
baselen = fill_directory(&dir, pathspec);
if (pathspec)
- prune_directory(&dir, pathspec, baselen);
+ seen = prune_directory(&dir, pathspec, baselen);
}
if (refresh_only) {
goto finish;
}
+ if (pathspec) {
+ int i;
+ if (!seen)
+ seen = find_used_pathspec(pathspec);
+ for (i = 0; pathspec[i]; i++) {
+ if (!seen[i] && pathspec[i][0]
+ && !file_exists(pathspec[i]))
+ die("pathspec '%s' did not match any files",
+ pathspec[i]);
+ }
+ free(seen);
+ }
+
exit_status |= add_files_to_cache(prefix, pathspec, flags);
if (add_new_files)
{
int i;
char *fixed_buf, *buf, *orig, *target;
+ int preimage_limit;
- if (preimage->nr + try_lno > img->nr)
+ if (preimage->nr + try_lno <= img->nr) {
+ /*
+ * The hunk falls within the boundaries of img.
+ */
+ preimage_limit = preimage->nr;
+ if (match_end && (preimage->nr + try_lno != img->nr))
+ return 0;
+ } else if (ws_error_action == correct_ws_error &&
+ (ws_rule & WS_BLANK_AT_EOF) && match_end) {
+ /*
+ * This hunk that matches at the end extends beyond
+ * the end of img, and we are removing blank lines
+ * at the end of the file. This many lines from the
+ * beginning of the preimage must match with img, and
+ * the remainder of the preimage must be blank.
+ */
+ preimage_limit = img->nr - try_lno;
+ } else {
+ /*
+ * The hunk extends beyond the end of the img and
+ * we are not removing blanks at the end, so we
+ * should reject the hunk at this position.
+ */
return 0;
+ }
if (match_beginning && try_lno)
return 0;
- if (match_end && preimage->nr + try_lno != img->nr)
- return 0;
-
/* Quick hash check */
- for (i = 0; i < preimage->nr; i++)
+ for (i = 0; i < preimage_limit; i++)
if (preimage->line[i].hash != img->line[try_lno + i].hash)
return 0;
- /*
- * Do we have an exact match? If we were told to match
- * at the end, size must be exactly at try+fragsize,
- * otherwise try+fragsize must be still within the preimage,
- * and either case, the old piece should match the preimage
- * exactly.
- */
- if ((match_end
- ? (try + preimage->len == img->len)
- : (try + preimage->len <= img->len)) &&
- !memcmp(img->buf + try, preimage->buf, preimage->len))
- return 1;
+ if (preimage_limit == preimage->nr) {
+ /*
+ * Do we have an exact match? If we were told to match
+ * at the end, size must be exactly at try+fragsize,
+ * otherwise try+fragsize must be still within the preimage,
+ * and either case, the old piece should match the preimage
+ * exactly.
+ */
+ if ((match_end
+ ? (try + preimage->len == img->len)
+ : (try + preimage->len <= img->len)) &&
+ !memcmp(img->buf + try, preimage->buf, preimage->len))
+ return 1;
+ } else {
+ /*
+ * The preimage extends beyond the end of img, so
+ * there cannot be an exact match.
+ *
+ * There must be one non-blank context line that match
+ * a line before the end of img.
+ */
+ char *buf_end;
+
+ buf = preimage->buf;
+ buf_end = buf;
+ for (i = 0; i < preimage_limit; i++)
+ buf_end += preimage->line[i].len;
+
+ for ( ; buf < buf_end; buf++)
+ if (!isspace(*buf))
+ break;
+ if (buf == buf_end)
+ return 0;
+ }
/*
* No exact match. If we are ignoring whitespace, run a line-by-line
size_t imgoff = 0;
size_t preoff = 0;
size_t postlen = postimage->len;
- for (i = 0; i < preimage->nr; i++) {
+ size_t extra_chars;
+ char *preimage_eof;
+ char *preimage_end;
+ for (i = 0; i < preimage_limit; i++) {
size_t prelen = preimage->line[i].len;
size_t imglen = img->line[try_lno+i].len;
}
/*
- * Ok, the preimage matches with whitespace fuzz. Update it and
- * the common postimage lines to use the same whitespace as the
- * target. imgoff now holds the true length of the target that
- * matches the preimage, and we need to update the line lengths
- * of the preimage to match the target ones.
+ * Ok, the preimage matches with whitespace fuzz.
+ *
+ * imgoff now holds the true length of the target that
+ * matches the preimage before the end of the file.
+ *
+ * Count the number of characters in the preimage that fall
+ * beyond the end of the file and make sure that all of them
+ * are whitespace characters. (This can only happen if
+ * we are removing blank lines at the end of the file.)
*/
- fixed_buf = xmalloc(imgoff);
- memcpy(fixed_buf, img->buf + try, imgoff);
- for (i = 0; i < preimage->nr; i++)
- preimage->line[i].len = img->line[try_lno+i].len;
+ buf = preimage_eof = preimage->buf + preoff;
+ for ( ; i < preimage->nr; i++)
+ preoff += preimage->line[i].len;
+ preimage_end = preimage->buf + preoff;
+ for ( ; buf < preimage_end; buf++)
+ if (!isspace(*buf))
+ return 0;
/*
- * Update the preimage buffer and the postimage context lines.
+ * Update the preimage and the common postimage context
+ * lines to use the same whitespace as the target.
+ * If whitespace is missing in the target (i.e.
+ * if the preimage extends beyond the end of the file),
+ * use the whitespace from the preimage.
*/
+ extra_chars = preimage_end - preimage_eof;
+ fixed_buf = xmalloc(imgoff + extra_chars);
+ memcpy(fixed_buf, img->buf + try, imgoff);
+ memcpy(fixed_buf + imgoff, preimage_eof, extra_chars);
+ imgoff += extra_chars;
update_pre_post_images(preimage, postimage,
fixed_buf, imgoff, postlen);
return 1;
* it might with whitespace fuzz. We haven't been asked to
* ignore whitespace, we were asked to correct whitespace
* errors, so let's try matching after whitespace correction.
+ *
+ * The preimage may extend beyond the end of the file,
+ * but in this loop we will only handle the part of the
+ * preimage that falls within the file.
*/
fixed_buf = xmalloc(preimage->len + 1);
buf = fixed_buf;
orig = preimage->buf;
target = img->buf + try;
- for (i = 0; i < preimage->nr; i++) {
+ for (i = 0; i < preimage_limit; i++) {
size_t fixlen; /* length after fixing the preimage */
size_t oldlen = preimage->line[i].len;
size_t tgtlen = img->line[try_lno + i].len;
target += tgtlen;
}
+
+ /*
+ * Now handle the lines in the preimage that falls beyond the
+ * end of the file (if any). They will only match if they are
+ * empty or only contain whitespace (if WS_BLANK_AT_EOL is
+ * false).
+ */
+ for ( ; i < preimage->nr; i++) {
+ size_t fixlen; /* length after fixing the preimage */
+ size_t oldlen = preimage->line[i].len;
+ int j;
+
+ /* Try fixing the line in the preimage */
+ fixlen = ws_fix_copy(buf, orig, oldlen, ws_rule, NULL);
+
+ for (j = 0; j < fixlen; j++)
+ if (!isspace(buf[j]))
+ goto unmatch_exit;
+
+ orig += oldlen;
+ buf += fixlen;
+ }
+
/*
* Yes, the preimage is based on an older version that still
* has whitespace breakages unfixed, and fixing them makes the
unsigned long backwards, forwards, try;
int backwards_lno, forwards_lno, try_lno;
- if (preimage->nr > img->nr)
- return -1;
-
/*
* If match_beginning or match_end is specified, there is no
* point starting from a wrong line that will never match and
else if (match_end)
line = img->nr - preimage->nr;
- if (line > img->nr)
+ /*
+ * Because the comparison is unsigned, the following test
+ * will also take care of a negative line number that can
+ * result when match_end and preimage is larger than the target.
+ */
+ if ((size_t) line > img->nr)
line = img->nr;
try = 0;
int i, nr;
size_t remove_count, insert_count, applied_at = 0;
char *result;
+ int preimage_limit;
+
+ /*
+ * If we are removing blank lines at the end of img,
+ * the preimage may extend beyond the end.
+ * If that is the case, we must be careful only to
+ * remove the part of the preimage that falls within
+ * the boundaries of img. Initialize preimage_limit
+ * to the number of lines in the preimage that falls
+ * within the boundaries.
+ */
+ preimage_limit = preimage->nr;
+ if (preimage_limit > img->nr - applied_pos)
+ preimage_limit = img->nr - applied_pos;
for (i = 0; i < applied_pos; i++)
applied_at += img->line[i].len;
remove_count = 0;
- for (i = 0; i < preimage->nr; i++)
+ for (i = 0; i < preimage_limit; i++)
remove_count += img->line[applied_pos + i].len;
insert_count = postimage->len;
result[img->len] = '\0';
/* Adjust the line table */
- nr = img->nr + postimage->nr - preimage->nr;
- if (preimage->nr < postimage->nr) {
+ nr = img->nr + postimage->nr - preimage_limit;
+ if (preimage_limit < postimage->nr) {
/*
* NOTE: this knows that we never call remove_first_line()
* on anything other than pre/post image.
img->line = xrealloc(img->line, nr * sizeof(*img->line));
img->line_allocated = img->line;
}
- if (preimage->nr != postimage->nr)
+ if (preimage_limit != postimage->nr)
memmove(img->line + applied_pos + postimage->nr,
- img->line + applied_pos + preimage->nr,
- (img->nr - (applied_pos + preimage->nr)) *
+ img->line + applied_pos + preimage_limit,
+ (img->nr - (applied_pos + preimage_limit)) *
sizeof(*img->line));
memcpy(img->line + applied_pos,
postimage->line,
if (applied_pos >= 0) {
if (new_blank_lines_at_end &&
- preimage.nr + applied_pos == img->nr &&
+ preimage.nr + applied_pos >= img->nr &&
(ws_rule & WS_BLANK_AT_EOF) &&
ws_error_action != nowarn_ws_error) {
record_ws_error(WS_BLANK_AT_EOF, "+", 1, frag->linenr);
f = fopen(file, "w");
if (!f)
- error("Unable to open marks file %s for writing.", file);
+ die_errno("Unable to open marks file %s for writing.", file);
for (i = 0; i < idnums.size; i++) {
if (deco->base && deco->base->type == 1) {
#include "sigchain.h"
static const char * const builtin_fetch_usage[] = {
- "git fetch [options] [<repository> <refspec>...]",
- "git fetch [options] <group>",
- "git fetch --multiple [options] [<repository> | <group>]...",
- "git fetch --all [options]",
+ "git fetch [<options>] [<repository> [<refspec>...]]",
+ "git fetch [<options>] <group>",
+ "git fetch --multiple [<options>] [<repository> | <group>]...",
+ "git fetch --all [<options>]",
NULL
};
* there is no entry in the resulting FETCH_HEAD marked
* for merging.
*/
+ memset(&refspec, 0, sizeof(refspec));
refspec.src = branch->merge[i]->src;
- refspec.dst = NULL;
- refspec.pattern = 0;
- refspec.force = 0;
get_fetch_map(remote_refs, &refspec, tail, 1);
for (rm = *old_tail; rm; rm = rm->next)
rm->merge = 1;
fputc(url[i], fp);
fputc('\n', fp);
- if (ref)
+ if (ref) {
rc |= update_local_ref(ref, what, note);
- else
+ free(ref);
+ } else
sprintf(note, "* %-*s %-*s -> FETCH_HEAD",
SUMMARY_WIDTH, *kind ? kind : "branch",
REFCOL_WIDTH, *what ? what : "HEAD");
* to fetch then we can mark the ref entry in the list
* as one to ignore by setting util to NULL.
*/
- if (!strcmp(ref->name + strlen(ref->name) - 3, "^{}")) {
+ if (!suffixcmp(ref->name, "^{}")) {
if (item && !has_sha1_file(ref->old_sha1) &&
!will_fetch(head, ref->old_sha1) &&
!has_sha1_file(item->util) &&
return 0;
}
- if (ignore_if_in_upstream)
+ if (ignore_if_in_upstream) {
+ /* Don't say anything if head and upstream are the same. */
+ if (rev.pending.nr == 2) {
+ struct object_array_entry *o = rev.pending.objects;
+ if (hashcmp(o[0].item->sha1, o[1].item->sha1) == 0)
+ return 0;
+ }
get_patch_ids(&rev, &ids, prefix);
+ }
if (!use_stdout)
realstdout = xfdopen(xdup(1), "w");
#include "parse-options.h"
static const char * const push_usage[] = {
- "git push [<options>] [<repository> <refspec>...]",
+ "git push [<options>] [<repository> [<refspec>...]]",
NULL,
};
static const char * const git_reset_usage[] = {
"git reset [--mixed | --soft | --hard | --merge] [-q] [<commit>]",
- "git reset [--mixed] <commit> [--] <paths>...",
+ "git reset [-q] <commit> [--] <paths>...",
+ "git reset --patch [<commit>] [--] [<paths>...]",
NULL
};
{
const char *ptr = value;
int len = value_len;
- int attr = -1;
+ unsigned int attr = 0;
int fg = -2;
int bg = -2;
return;
}
- /* [fg [bg]] [attr] */
+ /* [fg [bg]] [attr]... */
while (len > 0) {
const char *word = ptr;
int val, wordlen = 0;
goto bad;
}
val = parse_attr(word, wordlen);
- if (val < 0 || attr != -1)
+ if (0 <= val)
+ attr |= (1 << val);
+ else
goto bad;
- attr = val;
}
- if (attr >= 0 || fg >= 0 || bg >= 0) {
+ if (attr || fg >= 0 || bg >= 0) {
int sep = 0;
+ int i;
*dst++ = '\033';
*dst++ = '[';
- if (attr >= 0) {
- *dst++ = '0' + attr;
- sep++;
+
+ for (i = 0; attr; i++) {
+ unsigned bit = (1 << i);
+ if (!(attr & bit))
+ continue;
+ attr &= ~bit;
+ if (sep++)
+ *dst++ = ';';
+ *dst++ = '0' + i;
}
if (fg >= 0) {
if (sep++)
#ifndef COLOR_H
#define COLOR_H
-/* "\033[1;38;5;2xx;48;5;2xxm\0" is 23 bytes */
-#define COLOR_MAXLEN 24
+/* 2 + (2 * num_attrs) + 8 + 1 + 8 + 'm' + NUL */
+/* "\033[1;2;4;5;7;38;5;2xx;48;5;2xxm\0" */
+/*
+ * The maximum length of ANSI color sequence we would generate:
+ * - leading ESC '[' 2
+ * - attr + ';' 2 * 8 (e.g. "1;")
+ * - fg color + ';' 9 (e.g. "38;5;2xx;")
+ * - fg color + ';' 9 (e.g. "48;5;2xx;")
+ * - terminating 'm' NUL 2
+ *
+ * The above overcounts attr (we only use 5 not 8) and one semicolon
+ * but it is close enough.
+ */
+#define COLOR_MAXLEN 40
/*
* IMPORTANT: Due to the way these color codes are emulated on Windows,
((val & 0x000000ff) << 24));
}
+#undef bswap32
+
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
#define bswap32(x) ({ \
int fh, rc;
/* must have write permission */
- if ((fh = open(file_name, O_RDWR | O_BINARY)) < 0)
- return -1;
+ DWORD attrs = GetFileAttributes(file_name);
+ if (attrs != INVALID_FILE_ATTRIBUTES &&
+ (attrs & FILE_ATTRIBUTE_READONLY)) {
+ /* ignore errors here; open() will report them */
+ SetFileAttributes(file_name, attrs & ~FILE_ATTRIBUTE_READONLY);
+ }
+
+ if ((fh = open(file_name, O_RDWR | O_BINARY)) < 0) {
+ rc = -1;
+ goto revert_attrs;
+ }
time_t_to_filetime(times->modtime, &mft);
time_t_to_filetime(times->actime, &aft);
} else
rc = 0;
close(fh);
+
+revert_attrs:
+ if (attrs != INVALID_FILE_ATTRIBUTES &&
+ (attrs & FILE_ATTRIBUTE_READONLY)) {
+ /* ignore errors again */
+ SetFileAttributes(file_name, attrs);
+ }
return rc;
}
refs="${cur%/*}"
;;
*)
- if [ -e "$dir/HEAD" ]; then echo HEAD; fi
+ for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD; do
+ if [ -e "$dir/$i" ]; then echo $i; fi
+ done
format="refname:short"
refs="refs/tags refs/heads refs/remotes"
;;
*host = hostport;
*port = strrchr(hostport, ':');
if (*port) {
- *port = '\0';
+ **port = '\0';
++*port;
}
}
const char **arg = argv;
struct child_process child;
struct strbuf buf = STRBUF_INIT;
+ int err = 0;
temp = prepare_temp_file(spec->path, spec);
*arg++ = pgm;
child.use_shell = 1;
child.argv = argv;
child.out = -1;
- if (start_command(&child) != 0 ||
- strbuf_read(&buf, child.out, 0) < 0 ||
- finish_command(&child) != 0) {
- close(child.out);
- strbuf_release(&buf);
+ if (start_command(&child)) {
remove_tempfile();
- error("error running textconv command '%s'", pgm);
return NULL;
}
+
+ if (strbuf_read(&buf, child.out, 0) < 0)
+ err = error("error reading from textconv command '%s'", pgm);
close(child.out);
+
+ if (finish_command(&child) || err) {
+ strbuf_release(&buf);
+ remove_tempfile();
+ return NULL;
+ }
remove_tempfile();
return strbuf_detach(&buf, outsize);
return 0;
}
-static int in_pathspec(const char *path, int len, const struct path_simplify *simplify)
+/*
+ * This function tells us whether an excluded path matches a
+ * list of "interesting" pathspecs. That is, whether a path matched
+ * by any of the pathspecs could possibly be ignored by excluding
+ * the specified path. This can happen if:
+ *
+ * 1. the path is mentioned explicitly in the pathspec
+ *
+ * 2. the path is a directory prefix of some element in the
+ * pathspec
+ */
+static int exclude_matches_pathspec(const char *path, int len,
+ const struct path_simplify *simplify)
{
if (simplify) {
for (; simplify->path; simplify++) {
if (len == simplify->len
&& !memcmp(path, simplify->path, len))
return 1;
+ if (len < simplify->len
+ && simplify->path[len] == '/'
+ && !memcmp(path, simplify->path, len))
+ return 1;
}
}
return 0;
{
int exclude = excluded(dir, path, &dtype);
if (exclude && (dir->flags & DIR_COLLECT_IGNORED)
- && in_pathspec(path, *len, simplify))
+ && exclude_matches_pathspec(path, *len, simplify))
dir_add_ignored(dir, path, *len);
/*
next;
}
if ($arg eq '-g' || $arg eq '--gui') {
- my $tool = Git::command_oneline('config',
- 'diff.guitool');
- if (length($tool)) {
- $ENV{GIT_DIFF_TOOL} = $tool;
- }
+ eval {
+ my $tool = Git::command_oneline('config',
+ 'diff.guitool');
+ if (length($tool)) {
+ $ENV{GIT_DIFF_TOOL} = $tool;
+ }
+ };
next;
}
if ($arg eq '-y' || $arg eq '--no-prompt') {
log_arg= verbosity=
merge_args=
curr_branch=$(git symbolic-ref -q HEAD)
-curr_branch_short=$(echo "$curr_branch" | sed "s|refs/heads/||")
+curr_branch_short="${curr_branch#refs/heads/}"
rebase=$(git config --bool branch.$curr_branch_short.rebase)
while :
do
sub git_get_project_config {
my ($key, $type) = @_;
- # do we have project
- return unless (defined $project && defined $git_dir);
+ return unless defined $git_dir;
# key sanity check
return unless ($key);
/* ISSYMREF=01 and ISPACKED=02 are public interfaces */
#define REF_KNOWS_PEELED 04
+#define REF_BROKEN 010
struct ref_list {
struct ref_list *next;
list = get_ref_dir(ref, list);
continue;
}
- if (!resolve_ref(ref, sha1, 1, &flag))
+ if (!resolve_ref(ref, sha1, 1, &flag)) {
hashclr(sha1);
+ flag |= REF_BROKEN;
+ }
list = add_ref(ref, sha1, flag, list, NULL);
}
free(ref);
{
if (strncmp(base, entry->name, trim))
return 0;
- /* Is this a "negative ref" that represents a deleted ref? */
- if (is_null_sha1(entry->sha1))
- return 0;
+
if (!(flags & DO_FOR_EACH_INCLUDE_BROKEN)) {
+ if (entry->flag & REF_BROKEN)
+ return 0; /* ignore dangling symref */
if (!has_sha1_file(entry->sha1)) {
error("%s does not point to a valid object!", entry->name);
return 0;
'
-$test_case 'add (with different case)' '
+
+
+test_expect_failure 'add (with different case)' '
git reset --hard initial &&
rm camelcase &&
echo 1 >CamelCase &&
git add CamelCase &&
- test $(git ls-files | grep -i camelcase | wc -l) = 1
+ camel=$(git ls-files | grep -i camelcase) &&
+ test $(echo "$camel" | wc -l) = 1 &&
+ test "z$(git cat-file blob :$camel)" = z1
'
'
+test_expect_success '"add -u non-existent" should fail' '
+ test_must_fail git add -u non-existent &&
+ ! (git ls-files | grep "non-existent")
+'
+
test_done
--- /dev/null
+#!/bin/sh
+
+test_description='giving ignored paths to git add'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+ mkdir sub dir dir/sub &&
+ echo sub >.gitignore &&
+ echo ign >>.gitignore &&
+ for p in . sub dir dir/sub
+ do
+ >"$p/ign" &&
+ >"$p/file" || exit 1
+ done
+'
+
+for i in file dir/file dir 'd*'
+do
+ test_expect_success "no complaints for unignored $i" '
+ rm -f .git/index &&
+ git add "$i" &&
+ git ls-files "$i" >out &&
+ test -s out
+ '
+done
+
+for i in ign dir/ign dir/sub dir/sub/*ign sub/file sub sub/*
+do
+ test_expect_success "complaints for ignored $i" '
+ rm -f .git/index &&
+ test_must_fail git add "$i" 2>err &&
+ git ls-files "$i" >out &&
+ ! test -s out &&
+ grep -e "Use -f if" err &&
+ cat err
+ '
+
+ test_expect_success "complaints for ignored $i with unignored file" '
+ rm -f .git/index &&
+ test_must_fail git add "$i" file 2>err &&
+ git ls-files "$i" >out &&
+ ! test -s out &&
+ grep -e "Use -f if" err &&
+ cat err
+ '
+done
+
+for i in sub sub/*
+do
+ test_expect_success "complaints for ignored $i in dir" '
+ rm -f .git/index &&
+ (
+ cd dir &&
+ test_must_fail git add "$i" 2>err &&
+ git ls-files "$i" >out &&
+ ! test -s out &&
+ grep -e "Use -f if" err &&
+ cat err
+ )
+ '
+done
+
+for i in ign file
+do
+ test_expect_success "complaints for ignored $i in sub" '
+ rm -f .git/index &&
+ (
+ cd sub &&
+ test_must_fail git add "$i" 2>err &&
+ git ls-files "$i" >out &&
+ ! test -s out &&
+ grep -e "Use -f if" err &&
+ cat err
+ )
+ '
+done
+
+test_done
--- /dev/null
+#!/bin/sh
+
+test_description='git rebase --whitespace=fix
+
+This test runs git rebase --whitespace=fix and make sure that it works.
+'
+
+. ./test-lib.sh
+
+# prepare initial revision of "file" with a blank line at the end
+cat >file <<EOF
+a
+b
+c
+
+EOF
+
+# expected contents in "file" after rebase
+cat >expect-first <<EOF
+a
+b
+c
+EOF
+
+# prepare second revision of "file"
+cat >second <<EOF
+a
+b
+c
+
+d
+e
+f
+
+
+
+
+EOF
+
+# expected contents in second revision after rebase
+cat >expect-second <<EOF
+a
+b
+c
+
+d
+e
+f
+EOF
+
+test_expect_success 'blank line at end of file; extend at end of file' '
+ git commit --allow-empty -m "Initial empty commit" &&
+ git add file && git commit -m first &&
+ mv second file &&
+ git add file && git commit -m second &&
+ git rebase --whitespace=fix HEAD^^ &&
+ git diff --exit-code HEAD^:file expect-first &&
+ test_cmp file expect-second
+'
+
+# prepare third revision of "file"
+sed -e's/Z//' >third <<EOF
+a
+b
+c
+
+d
+e
+f
+ Z
+ Z
+h
+i
+j
+k
+l
+EOF
+
+sed -e's/ //g' <third >expect-third
+
+test_expect_success 'two blanks line at end of file; extend at end of file' '
+ cp third file && git add file && git commit -m third &&
+ git rebase --whitespace=fix HEAD^^ &&
+ git diff --exit-code HEAD^:file expect-second &&
+ test_cmp file expect-third
+'
+
+test_expect_success 'same, but do not remove trailing spaces' '
+ git config core.whitespace "-blank-at-eol" &&
+ git reset --hard HEAD^ &&
+ cp third file && git add file && git commit -m third &&
+ git rebase --whitespace=fix HEAD^^
+ git diff --exit-code HEAD^:file expect-second &&
+ test_cmp file third
+'
+
+sed -e's/Z//' >beginning <<EOF
+a
+ Z
+ Z
+EOF
+
+cat >expect-beginning <<EOF
+a
+
+
+1
+2
+3
+4
+5
+EOF
+
+test_expect_success 'at beginning of file' '
+ git config core.whitespace "blank-at-eol" &&
+ cp beginning file &&
+ git commit -m beginning file &&
+ for i in 1 2 3 4 5; do
+ echo $i
+ done >> file &&
+ git commit -m more file &&
+ git rebase --whitespace=fix HEAD^^ &&
+ test_cmp file expect-beginning
+'
+
+test_done
git add track-this
'
+test_expect_success '"add non-existent" should fail' '
+ test_must_fail git add non-existent &&
+ ! (git ls-files | grep "non-existent")
+'
+
test_done
! grep "Use .--" error
'
+test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
+ git format-patch --ignore-if-in-upstream HEAD
+'
+
test_done
color()
{
- git config diff.color.new "$1" &&
- test "`git config --get-color diff.color.new`" = "\e$2"
+ actual=$(git config --get-color no.such.slot "$1") &&
+ test "$actual" = "\e$2"
}
invalid_color()
{
- git config diff.color.new "$1" &&
- test -z "`git config --get-color diff.color.new 2>/dev/null`"
+ test_must_fail git config --get-color no.such.slot "$1"
}
test_expect_success 'reset' '
color "blue red ul" "[4;34;41m"
'
+test_expect_success 'fg bg attr...' '
+ color "blue bold dim ul blink reverse" "[1;2;4;5;7;34m"
+'
+
+test_expect_success 'long color specification' '
+ color "254 255 bold dim ul blink reverse" "[1;2;4;5;7;38;5;254;48;5;255m"
+'
+
test_expect_success '256 colors' '
color "254 bold 255" "[1;38;5;254;48;5;255m"
'
'
+test_expect_success 'apply patch with 3 context lines matching at end' '
+ { echo a; echo b; echo c; echo d; } >file &&
+ git add file &&
+ echo e >>file &&
+ git diff >patch &&
+ >file &&
+ test_must_fail git apply patch
+'
+
test_done
grep "new blank line at EOF" error
'
+test_expect_success 'applying beyond EOF requires one non-blank context line' '
+ { echo; echo; echo; echo; } >one &&
+ git add one &&
+ { echo b; } >>one &&
+ git diff -- one >patch &&
+
+ git checkout one &&
+ { echo a; echo; } >one &&
+ cp one expect &&
+ test_must_fail git apply --whitespace=fix patch &&
+ test_cmp one expect &&
+ test_must_fail git apply --ignore-space-change --whitespace=fix patch &&
+ test_cmp one expect
+'
+
+test_expect_success 'tons of blanks at EOF should not apply' '
+ for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16; do
+ echo; echo; echo; echo;
+ done >one &&
+ git add one &&
+ echo a >>one &&
+ git diff -- one >patch &&
+
+ >one &&
+ test_must_fail git apply --whitespace=fix patch &&
+ test_must_fail git apply --ignore-space-change --whitespace=fix patch
+'
+
+test_expect_success 'missing blank line at end with --whitespace=fix' '
+ echo a >one &&
+ echo >>one &&
+ git add one &&
+ echo b >>one &&
+ cp one expect &&
+ git diff -- one >patch &&
+ echo a >one &&
+ cp one saved-one &&
+ test_must_fail git apply patch &&
+ git apply --whitespace=fix patch &&
+ test_cmp one expect &&
+ mv saved-one one &&
+ git apply --ignore-space-change --whitespace=fix patch &&
+ test_cmp one expect
+'
+
+test_expect_success 'two missing blank lines at end with --whitespace=fix' '
+ { echo a; echo; echo b; echo c; } >one &&
+ cp one no-blank-lines &&
+ { echo; echo; } >>one &&
+ git add one &&
+ echo d >>one &&
+ cp one expect &&
+ echo >>one &&
+ git diff -- one >patch &&
+ cp no-blank-lines one &&
+ test_must_fail git apply patch &&
+ git apply --whitespace=fix patch &&
+ test_cmp one expect &&
+ mv no-blank-lines one &&
+ test_must_fail git apply patch &&
+ git apply --ignore-space-change --whitespace=fix patch &&
+ test_cmp one expect
+'
+
+test_expect_success 'shrink file with tons of missing blanks at end of file' '
+ { echo a; echo b; echo c; } >one &&
+ cp one no-blank-lines &&
+ for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16; do
+ echo; echo; echo; echo;
+ done >>one &&
+ git add one &&
+ echo a >one &&
+ cp one expect &&
+ git diff -- one >patch &&
+ cp no-blank-lines one &&
+ test_must_fail git apply patch &&
+ git apply --whitespace=fix patch &&
+ test_cmp one expect &&
+ mv no-blank-lines one &&
+ git apply --ignore-space-change --whitespace=fix patch &&
+ test_cmp one expect
+'
+
+test_expect_success 'missing blanks at EOF must only match blank lines' '
+ { echo a; echo b; } >one &&
+ git add one &&
+ { echo c; echo d; } >>one &&
+ git diff -- one >patch &&
+
+ echo a >one &&
+ test_must_fail git apply patch
+ test_must_fail git apply --whitespace=fix patch &&
+ test_must_fail git apply --ignore-space-change --whitespace=fix patch
+'
+
+sed -e's/Z//' >one <<EOF
+a
+b
+c
+ Z
+EOF
+
+test_expect_success 'missing blank line should match context line with spaces' '
+ git add one &&
+ echo d >>one &&
+ git diff -- one >patch &&
+ { echo a; echo b; echo c; } >one &&
+ cp one expect &&
+ { echo; echo d; } >>expect &&
+ git add one &&
+
+ git apply --whitespace=fix patch &&
+ test_cmp one expect
+'
+
+sed -e's/Z//' >one <<EOF
+a
+b
+c
+ Z
+EOF
+
+test_expect_success 'same, but with the --ignore-space-option' '
+ git add one &&
+ echo d >>one &&
+ cp one expect &&
+ git diff -- one >patch &&
+ { echo a; echo b; echo c; } >one &&
+ git add one &&
+
+ git checkout-index -f one &&
+ git apply --ignore-space-change --whitespace=fix patch &&
+ test_cmp one expect
+'
+
+test_expect_success 'same, but with CR-LF line endings && cr-at-eol set' '
+ git config core.whitespace cr-at-eol &&
+ printf "a\r\n" >one &&
+ printf "b\r\n" >>one &&
+ printf "c\r\n" >>one &&
+ cp one save-one &&
+ printf " \r\n" >>one
+ git add one &&
+ printf "d\r\n" >>one &&
+ cp one expect &&
+ git diff -- one >patch &&
+ mv save-one one &&
+
+ git apply --ignore-space-change --whitespace=fix patch &&
+ test_cmp one expect
+'
+
+test_expect_success 'same, but with CR-LF line endings && cr-at-eol unset' '
+ git config --unset core.whitespace &&
+ printf "a\r\n" >one &&
+ printf "b\r\n" >>one &&
+ printf "c\r\n" >>one &&
+ cp one save-one &&
+ printf " \r\n" >>one
+ git add one &&
+ cp one expect &&
+ printf "d\r\n" >>one &&
+ git diff -- one >patch &&
+ mv save-one one &&
+ echo d >>expect &&
+
+ git apply --ignore-space-change --whitespace=fix patch &&
+ test_cmp one expect
+'
+
test_done
(
cd seven &&
git remote prune origin
- ) 2>err &&
+ ) >err 2>&1 &&
grep "has become dangling" err &&
- : And the dangling symref will not cause other annoying errors
+ : And the dangling symref will not cause other annoying errors &&
(
cd seven &&
git branch -a
) 2>err &&
- ! grep "points nowhere" err
+ ! grep "points nowhere" err &&
(
cd seven &&
test_must_fail git branch nomore origin
restore_test_defaults
'
+test_expect_success 'difftool --gui works without configured diff.guitool' '
+ git config diff.tool test-tool &&
+
+ diff=$(git difftool --no-prompt --gui branch) &&
+ test "$diff" = "branch" &&
+
+ restore_test_defaults
+'
+
# Specify the diff tool using $GIT_DIFF_TOOL
test_expect_success 'GIT_DIFF_TOOL variable' '
git config --unset diff.tool
git checkout -f master &&
mkdir sub &&
- cd sub &&
- git init &&
- echo test file > file &&
- git add file &&
- git commit -m sub_initial &&
- cd .. &&
+ (
+ cd sub &&
+ git init &&
+ echo test file > file &&
+ git add file &&
+ git commit -m sub_initial
+ ) &&
git submodule add "`pwd`/sub" sub &&
git commit -m initial &&
test_tick &&
- cd sub &&
- echo more data >> file &&
- git add file &&
- git commit -m sub_second &&
- cd .. &&
+ (
+ cd sub &&
+ echo more data >> file &&
+ git add file &&
+ git commit -m sub_second
+ ) &&
git add sub &&
git commit -m second
test_expect_success 'setup for limiting exports by PATH' '
mkdir limit-by-paths &&
- cd limit-by-paths &&
- git init &&
- echo hi > there &&
- git add there &&
- git commit -m "First file" &&
- echo foo > bar &&
- git add bar &&
- git commit -m "Second file" &&
- git tag -a -m msg mytag &&
- echo morefoo >> bar &&
- git add bar &&
- git commit -m "Change to second file" &&
- cd ..
+ (
+ cd limit-by-paths &&
+ git init &&
+ echo hi > there &&
+ git add there &&
+ git commit -m "First file" &&
+ echo foo > bar &&
+ git add bar &&
+ git commit -m "Second file" &&
+ git tag -a -m msg mytag &&
+ echo morefoo >> bar &&
+ git add bar &&
+ git commit -m "Change to second file"
+ )
'
cat > limit-by-paths/expected << EOF
EOF
test_expect_success 'dropping tag of filtered out object' '
+(
cd limit-by-paths &&
git fast-export --tag-of-filtered-object=drop mytag -- there > output &&
- test_cmp output expected &&
- cd ..
+ test_cmp output expected
+)
'
cat >> limit-by-paths/expected << EOF
EOF
test_expect_success 'rewriting tag of filtered out object' '
+(
cd limit-by-paths &&
git fast-export --tag-of-filtered-object=rewrite mytag -- there > output &&
- test_cmp output expected &&
- cd ..
+ test_cmp output expected
+)
'
cat > limit-by-paths/expected << EOF
EOF
test_expect_failure 'no exact-ref revisions included' '
- cd limit-by-paths &&
- git fast-export master~2..master~1 > output &&
- test_cmp output expected &&
- cd ..
+ (
+ cd limit-by-paths &&
+ git fast-export master~2..master~1 > output &&
+ test_cmp output expected
+ )
'
-
test_expect_success 'set-up a few more tags for tag export tests' '
git checkout -f master &&
HEAD_TREE=`git show -s --pretty=raw HEAD | grep tree | sed "s/tree //"` &&