Compare commits
91 Commits
Author | SHA1 | Date | |
---|---|---|---|
5c415311f7 | |||
692be9f365 | |||
f630171d9d | |||
46cdcc6275 | |||
67b175bb11 | |||
e5bde1987c | |||
e2355a3e06 | |||
9e3248eb51 | |||
5cb0f2745f | |||
d4029d30c7 | |||
b619715207 | |||
b938f62a20 | |||
950db8798d | |||
674a1d2628 | |||
69274b6e87 | |||
89edd5a901 | |||
391d186bab | |||
98347fee9b | |||
9d3043cf33 | |||
78f111e12d | |||
3aed2fda6f | |||
8ee09acd8f | |||
466ddf90c2 | |||
20642801e4 | |||
bf474e2402 | |||
9968696015 | |||
2454ac7b9f | |||
ebb7bbf769 | |||
f8aa1b6902 | |||
dc7f55cbe9 | |||
944019c8b3 | |||
eb475bfa05 | |||
914186a5c3 | |||
8dca683346 | |||
be17262d13 | |||
3772923f14 | |||
4f8b8992ef | |||
3d1d81eba2 | |||
8faea4f3b2 | |||
885a1ffb93 | |||
94468bc1f7 | |||
9e8f6e7f6e | |||
ae5a97fdd0 | |||
1cbe69f649 | |||
12dd111288 | |||
47a845bfc3 | |||
9279bf3ab6 | |||
687004b512 | |||
4fc988efe6 | |||
68c2ec7f43 | |||
a324fc45e4 | |||
c6dbca08ca | |||
e423ffd8a6 | |||
152d70f728 | |||
141201d124 | |||
8a124b82a0 | |||
cec08717cc | |||
50a4b35245 | |||
7b9e3ce025 | |||
837e5fe95d | |||
6b9315d5a1 | |||
0ddd93b271 | |||
c7719fbe46 | |||
2ce53f9b77 | |||
22b3ddd508 | |||
dcfdbdf08b | |||
3442ea4a75 | |||
1f7903a371 | |||
11b8a41c45 | |||
d99bf51add | |||
936b7057e8 | |||
a9e67c8ccc | |||
bd7c6e7fc5 | |||
fb3bb3d132 | |||
a9012e343e | |||
f611c8c0d1 | |||
fcd3549ef2 | |||
f83b9ba209 | |||
3a882d9696 | |||
f53bd743ff | |||
88c44735ab | |||
a010966844 | |||
4deba8b779 | |||
6720e95b30 | |||
a583971f15 | |||
c569b1fee1 | |||
81dc223deb | |||
36e3b5eafe | |||
e1f33efe07 | |||
c5ab03f26c | |||
7bb1fcc6fc |
59
Documentation/RelNotes-1.6.1.1.txt
Normal file
59
Documentation/RelNotes-1.6.1.1.txt
Normal file
@ -0,0 +1,59 @@
|
||||
GIT v1.6.1.1 Release Notes
|
||||
==========================
|
||||
|
||||
Fixes since v1.6.1
|
||||
------------------
|
||||
|
||||
* "git add frotz/nitfol" when "frotz" is a submodule should have errored
|
||||
out, but it didn't.
|
||||
|
||||
* "git apply" took file modes from the patch text and updated the mode
|
||||
bits of the target tree even when the patch was not about mode changes.
|
||||
|
||||
* "git bisect view" on Cygwin did not launch gitk
|
||||
|
||||
* "git checkout $tree" did not trigger an error.
|
||||
|
||||
* "git commit" tried to remove COMMIT_EDITMSG from the work tree by mistake.
|
||||
|
||||
* "git describe --all" complained when a commit is described with a tag,
|
||||
which was nonsense.
|
||||
|
||||
* "git diff --no-index --" did not trigger no-index (aka "use git-diff as
|
||||
a replacement of diff on untracked files") behaviour.
|
||||
|
||||
* "git format-patch -1 HEAD" on a root commit failed to produce patch
|
||||
text.
|
||||
|
||||
* "git fsck branch" did not work as advertised; instead it behaved the same
|
||||
way as "git fsck".
|
||||
|
||||
* "git log --pretty=format:%s" did not handle a multi-line subject the
|
||||
same way as built-in log listers (i.e. shortlog, --pretty=oneline, etc.)
|
||||
|
||||
* "git daemon", and "git merge-file" are more careful when freopen fails
|
||||
and barf, instead of going on and writing to unopened filehandle.
|
||||
|
||||
* "git http-push" did not like some RFC 4918 compliant DAV server
|
||||
responses.
|
||||
|
||||
* "git merge -s recursive" mistakenly overwritten an untracked file in the
|
||||
work tree upon delete/modify conflict.
|
||||
|
||||
* "git merge -s recursive" didn't leave the index unmerged for entries with
|
||||
rename/delete conflictd.
|
||||
|
||||
* "git merge -s recursive" clobbered untracked files in the work tree.
|
||||
|
||||
* "git mv -k" with more than one errorneous paths misbehaved.
|
||||
|
||||
* "git read-tree -m -u" hence branch switching incorrectly lost a
|
||||
subdirectory in rare cases.
|
||||
|
||||
* "git rebase -i" issued an unnecessary error message upon a user error of
|
||||
marking the first commit to be "squash"ed.
|
||||
|
||||
* "git shortlog" did not format a commit message with multi-line
|
||||
subject correctly.
|
||||
|
||||
Many documentation updates.
|
@ -635,7 +635,7 @@ diff.renames::
|
||||
will enable basic rename detection. If set to "copies" or
|
||||
"copy", it will detect copies, as well.
|
||||
|
||||
diff.suppress-blank-empty::
|
||||
diff.suppressBlankEmpty::
|
||||
A boolean to inhibit the standard behavior of printing a space
|
||||
before each empty output line. Defaults to false.
|
||||
|
||||
|
@ -19,16 +19,12 @@ endif::git-format-patch[]
|
||||
|
||||
ifndef::git-format-patch[]
|
||||
-p::
|
||||
-u::
|
||||
Generate patch (see section on generating patches).
|
||||
{git-diff? This is the default.}
|
||||
endif::git-format-patch[]
|
||||
|
||||
-u::
|
||||
Synonym for "-p".
|
||||
|
||||
-U<n>::
|
||||
Shorthand for "--unified=<n>".
|
||||
|
||||
--unified=<n>::
|
||||
Generate diffs with <n> lines of context instead of
|
||||
the usual three. Implies "-p".
|
||||
@ -190,31 +186,25 @@ endif::git-format-patch[]
|
||||
can name which subdirectory to make the output relative
|
||||
to by giving a <path> as an argument.
|
||||
|
||||
-a::
|
||||
--text::
|
||||
Treat all files as text.
|
||||
|
||||
-a::
|
||||
Shorthand for "--text".
|
||||
|
||||
--ignore-space-at-eol::
|
||||
Ignore changes in whitespace at EOL.
|
||||
|
||||
-b::
|
||||
--ignore-space-change::
|
||||
Ignore changes in amount of whitespace. This ignores whitespace
|
||||
at line end, and considers all other sequences of one or
|
||||
more whitespace characters to be equivalent.
|
||||
|
||||
-b::
|
||||
Shorthand for "--ignore-space-change".
|
||||
|
||||
-w::
|
||||
--ignore-all-space::
|
||||
Ignore whitespace when comparing lines. This ignores
|
||||
differences even if one line has whitespace where the other
|
||||
line has none.
|
||||
|
||||
-w::
|
||||
Shorthand for "--ignore-all-space".
|
||||
|
||||
--exit-code::
|
||||
Make the program exit with codes similar to diff(1).
|
||||
That is, it exits with 1 if there were differences and
|
||||
|
@ -43,7 +43,7 @@ OPTIONS
|
||||
Automatically implies --tags.
|
||||
|
||||
--abbrev=<n>::
|
||||
Instead of using the default 8 hexadecimal digits as the
|
||||
Instead of using the default 7 hexadecimal digits as the
|
||||
abbreviated object name, use <n> digits.
|
||||
|
||||
--candidates=<n>::
|
||||
|
@ -21,7 +21,10 @@ OPTIONS
|
||||
-------
|
||||
include::diff-options.txt[]
|
||||
|
||||
-1 -2 -3 or --base --ours --theirs, and -0::
|
||||
-1 --base::
|
||||
-2 --ours::
|
||||
-3 --theirs::
|
||||
-0::
|
||||
Diff against the "base" version, "our branch" or "their
|
||||
branch" respectively. With these options, diffs for
|
||||
merged entries are not shown.
|
||||
|
@ -28,7 +28,9 @@ OPTIONS
|
||||
-------
|
||||
<repository>::
|
||||
The "remote" repository that is destination of a push
|
||||
operation. See the section <<URLS,GIT URLS>> below.
|
||||
operation. This parameter can be either a URL
|
||||
(see the section <<URLS,GIT URLS>> below) or the name
|
||||
of a remote (see the section <<REMOTES,REMOTES>> below).
|
||||
|
||||
<refspec>...::
|
||||
The canonical format of a <refspec> parameter is
|
||||
@ -42,22 +44,21 @@ tip of `master` branch); see linkgit:git-rev-parse[1]) that you
|
||||
want to push. The <dst> side represents the destination location.
|
||||
+
|
||||
The local ref that matches <src> is used
|
||||
to fast forward the remote ref that matches <dst> (or, if no <dst> was
|
||||
specified, the same ref that <src> referred to locally). If
|
||||
to fast forward the remote ref that matches <dst>. If
|
||||
the optional leading plus `+` is used, the remote ref is updated
|
||||
even if it does not result in a fast forward update.
|
||||
+
|
||||
`tag <tag>` means the same as `refs/tags/<tag>:refs/tags/<tag>`.
|
||||
+
|
||||
A parameter <ref> without a colon pushes the <ref> from the source
|
||||
repository to the destination repository under the same name.
|
||||
A lonely <src> parameter (without a colon and a destination) pushes
|
||||
the <src> to the same name in the destination repository.
|
||||
+
|
||||
Pushing an empty <src> allows you to delete the <dst> ref from
|
||||
the remote repository.
|
||||
+
|
||||
The special refspec `:` (or `+:` to allow non-fast forward updates)
|
||||
directs git to push "matching" heads: for every head that exists on
|
||||
the local side, the remote side is updated if a head of the same name
|
||||
directs git to push "matching" branches: for every branch that exists on
|
||||
the local side, the remote side is updated if a branch of the same name
|
||||
already exists on the remote side. This is the default operation mode
|
||||
if no explicit refspec is found (that is neither on the command line
|
||||
nor in any Push line of the corresponding remotes file---see below).
|
||||
@ -86,14 +87,12 @@ nor in any Push line of the corresponding remotes file---see below).
|
||||
line.
|
||||
|
||||
--receive-pack=<git-receive-pack>::
|
||||
--exec=<git-receive-pack>::
|
||||
Path to the 'git-receive-pack' program on the remote
|
||||
end. Sometimes useful when pushing to a remote
|
||||
repository over ssh, and you do not have the program in
|
||||
a directory on the default $PATH.
|
||||
|
||||
--exec=<git-receive-pack>::
|
||||
Same as \--receive-pack=<git-receive-pack>.
|
||||
|
||||
-f::
|
||||
--force::
|
||||
Usually, the command refuses to update a remote ref that is
|
||||
|
@ -34,6 +34,7 @@ The --bcc option must be repeated for each user you want on the bcc list.
|
||||
|
||||
--cc::
|
||||
Specify a starting "Cc:" value for each email.
|
||||
Default is the value of 'sendemail.cc'.
|
||||
+
|
||||
The --cc option must be repeated for each user you want on the cc list.
|
||||
|
||||
@ -197,12 +198,6 @@ Administering
|
||||
--[no-]validate::
|
||||
Perform sanity checks on patches.
|
||||
Currently, validation means the following:
|
||||
|
||||
--[no-]format-patch::
|
||||
When an argument may be understood either as a reference or as a file name,
|
||||
choose to understand it as a format-patch argument ('--format-patch')
|
||||
or as a file name ('--no-format-patch'). By default, when such a conflict
|
||||
occurs, git send-email will fail.
|
||||
+
|
||||
--
|
||||
* Warn of patches that contain lines longer than 998 characters; this
|
||||
@ -212,6 +207,12 @@ Administering
|
||||
Default is the value of 'sendemail.validate'; if this is not set,
|
||||
default to '--validate'.
|
||||
|
||||
--[no-]format-patch::
|
||||
When an argument may be understood either as a reference or as a file name,
|
||||
choose to understand it as a format-patch argument ('--format-patch')
|
||||
or as a file name ('--no-format-patch'). By default, when such a conflict
|
||||
occurs, git send-email will fail.
|
||||
|
||||
|
||||
CONFIGURATION
|
||||
-------------
|
||||
|
@ -18,8 +18,9 @@ of server-side GIT commands implementing the pull/push functionality.
|
||||
The commands can be executed only by the '-c' option; the shell is not
|
||||
interactive.
|
||||
|
||||
Currently, only the 'git-receive-pack' and 'git-upload-pack' commands
|
||||
are permitted to be called, with a single required argument.
|
||||
Currently, only three commands are permitted to be called, 'git-receive-pack'
|
||||
'git-upload-pack' with a single required argument or 'cvs server' (to invoke
|
||||
'git-cvsserver').
|
||||
|
||||
Author
|
||||
------
|
||||
|
@ -48,15 +48,41 @@ OPTIONS
|
||||
FILES
|
||||
-----
|
||||
|
||||
If the file `.mailmap` exists, it will be used for mapping author
|
||||
email addresses to a real author name. One mapping per line, first
|
||||
the author name followed by the email address enclosed by
|
||||
'<' and '>'. Use hash '#' for comments. Example:
|
||||
If a file `.mailmap` exists at the toplevel of the repository,
|
||||
it is used to map an author email address to a canonical real name. This
|
||||
can be used to coalesce together commits by the same person where their
|
||||
name was spelled differently (whether with the same email address or
|
||||
not).
|
||||
|
||||
Each line in the file consists, in this order, of the canonical real name
|
||||
of an author, whitespace, and an email address (enclosed by '<' and '>')
|
||||
to map to the name. Use hash '#' for comments, either on their own line,
|
||||
or after the email address.
|
||||
|
||||
A canonical name may appear in more than one line, associated with
|
||||
different email addresses, but it doesn't make sense for a given address
|
||||
to appear more than once (if that happens, a later line overrides the
|
||||
earlier ones).
|
||||
|
||||
So, for example, if your history contains commits by two authors, Jane
|
||||
and Joe, whose names appear in the repository under several forms:
|
||||
|
||||
------------
|
||||
# Keep alphabetized
|
||||
Adam Morrow <adam@localhost.localdomain>
|
||||
Eve Jones <eve@laptop.(none)>
|
||||
Joe Developer <joe@example.com>
|
||||
Joe R. Developer <joe@example.com>
|
||||
Jane Doe <jane@example.com>
|
||||
Jane Doe <jane@laptop.(none)>
|
||||
Jane D. <jane@desktop.(none)>
|
||||
------------
|
||||
|
||||
Then, supposing Joe wants his middle name initial used, and Jane prefers
|
||||
her family name fully spelled out, a proper `.mailmap` file would look like:
|
||||
|
||||
------------
|
||||
# Note how we don't need an entry for <jane@laptop.(none)>, because the
|
||||
# real name of that author is correct already, and coalesced directly.
|
||||
Jane Doe <jane@desktop.(none)>
|
||||
Joe R. Developer <joe@random.com>
|
||||
------------
|
||||
|
||||
Author
|
||||
|
@ -70,7 +70,7 @@ OPTIONS
|
||||
|
||||
-m <msg>::
|
||||
Use the given tag message (instead of prompting).
|
||||
If multiple `-m` options are given, there values are
|
||||
If multiple `-m` options are given, their values are
|
||||
concatenated as separate paragraphs.
|
||||
Implies `-a` if none of `-a`, `-s`, or `-u <key-id>`
|
||||
is given.
|
||||
@ -207,7 +207,7 @@ determines who are interested in whose tags.
|
||||
|
||||
A one-shot pull is a sign that a commit history is now crossing
|
||||
the boundary between one circle of people (e.g. "people who are
|
||||
primarily interested in networking part of the kernel") who may
|
||||
primarily interested in the networking part of the kernel") who may
|
||||
have their own set of tags (e.g. "this is the third release
|
||||
candidate from the networking group to be proposed for general
|
||||
consumption with 2.6.21 release") to another circle of people
|
||||
|
@ -90,7 +90,7 @@ This hook is invoked by 'git-commit' right after preparing the
|
||||
default log message, and before the editor is started.
|
||||
|
||||
It takes one to three parameters. The first is the name of the file
|
||||
that the commit log message. The second is the source of the commit
|
||||
that contains the commit log message. The second is the source of the commit
|
||||
message, and can be: `message` (if a `-m` or `-F` option was
|
||||
given); `template` (if a `-t` option was given or the
|
||||
configuration option `commit.template` is set); `merge` (if the
|
||||
|
@ -590,7 +590,7 @@ list. When the history has lines of development that diverged and
|
||||
then merged back together, the order in which 'git-log' presents
|
||||
those commits is meaningless.
|
||||
|
||||
Most projects with multiple contributors (such as the linux kernel,
|
||||
Most projects with multiple contributors (such as the Linux kernel,
|
||||
or git itself) have frequent merges, and 'gitk' does a better job of
|
||||
visualizing their history. For example,
|
||||
|
||||
@ -642,7 +642,7 @@ digressions that may be interesting at this point are:
|
||||
|
||||
* linkgit:git-format-patch[1], linkgit:git-am[1]: These convert
|
||||
series of git commits into emailed patches, and vice versa,
|
||||
useful for projects such as the linux kernel which rely heavily
|
||||
useful for projects such as the Linux kernel which rely heavily
|
||||
on emailed patches.
|
||||
|
||||
* linkgit:git-bisect[1]: When there is a regression in your
|
||||
|
@ -59,7 +59,7 @@ project in mind, here are some interesting examples:
|
||||
------------------------------------------------
|
||||
# git itself (approx. 10MB download):
|
||||
$ git clone git://git.kernel.org/pub/scm/git/git.git
|
||||
# the linux kernel (approx. 150MB download):
|
||||
# the Linux kernel (approx. 150MB download):
|
||||
$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
|
||||
------------------------------------------------
|
||||
|
||||
@ -1009,7 +1009,7 @@ $ git init
|
||||
If you have some initial content (say, a tarball):
|
||||
|
||||
-------------------------------------------------
|
||||
$ tar -xzvf project.tar.gz
|
||||
$ tar xzvf project.tar.gz
|
||||
$ cd project
|
||||
$ git init
|
||||
$ git add . # include everything below ./ in the first commit:
|
||||
@ -1340,7 +1340,7 @@ These will display all commits which exist only on HEAD or on
|
||||
MERGE_HEAD, and which touch an unmerged file.
|
||||
|
||||
You may also use linkgit:git-mergetool[1], which lets you merge the
|
||||
unmerged files using external tools such as emacs or kdiff3.
|
||||
unmerged files using external tools such as Emacs or kdiff3.
|
||||
|
||||
Each time you resolve the conflicts in a file and update the index:
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
GVF=GIT-VERSION-FILE
|
||||
DEF_VER=v1.6.0.2.GIT
|
||||
DEF_VER=v1.6.1.1.GIT
|
||||
|
||||
LF='
|
||||
'
|
||||
|
2
README
2
README
@ -24,7 +24,7 @@ It was originally written by Linus Torvalds with help of a group of
|
||||
hackers around the net. It is currently maintained by Junio C Hamano.
|
||||
|
||||
Please read the file INSTALL for installation instructions.
|
||||
See Documentation/tutorial.txt to get started, then see
|
||||
See Documentation/gittutorial.txt to get started, then see
|
||||
Documentation/everyday.txt for a useful minimum set of commands,
|
||||
and "man git-commandname" for documentation of each command.
|
||||
CVS users may also want to read Documentation/cvs-migration.txt.
|
||||
|
@ -68,6 +68,33 @@ static void prune_directory(struct dir_struct *dir, const char **pathspec, int p
|
||||
free(seen);
|
||||
}
|
||||
|
||||
static void treat_gitlinks(const char **pathspec)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!pathspec || !*pathspec)
|
||||
return;
|
||||
|
||||
for (i = 0; i < active_nr; i++) {
|
||||
struct cache_entry *ce = active_cache[i];
|
||||
if (S_ISGITLINK(ce->ce_mode)) {
|
||||
int len = ce_namelen(ce), j;
|
||||
for (j = 0; pathspec[j]; j++) {
|
||||
int len2 = strlen(pathspec[j]);
|
||||
if (len2 <= len || pathspec[j][len] != '/' ||
|
||||
memcmp(ce->name, pathspec[j], len))
|
||||
continue;
|
||||
if (len2 == len + 1)
|
||||
/* strip trailing slash */
|
||||
pathspec[j] = xstrndup(ce->name, len);
|
||||
else
|
||||
die ("Path '%s' is in submodule '%.*s'",
|
||||
pathspec[j], len, ce->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void fill_directory(struct dir_struct *dir, const char **pathspec,
|
||||
int ignored_too)
|
||||
{
|
||||
@ -261,6 +288,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
|
||||
|
||||
if (read_cache() < 0)
|
||||
die("index file corrupt");
|
||||
treat_gitlinks(pathspec);
|
||||
|
||||
if (add_new_files)
|
||||
/* This picks up the paths that are not tracked */
|
||||
|
@ -630,7 +630,7 @@ static int gitdiff_index(const char *line, struct patch *patch)
|
||||
memcpy(patch->new_sha1_prefix, line, len);
|
||||
patch->new_sha1_prefix[len] = 0;
|
||||
if (*ptr == ' ')
|
||||
patch->new_mode = patch->old_mode = strtoul(ptr+1, NULL, 8);
|
||||
patch->old_mode = strtoul(ptr+1, NULL, 8);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2447,6 +2447,8 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s
|
||||
if (st_mode != patch->old_mode)
|
||||
fprintf(stderr, "warning: %s has type %o, expected %o\n",
|
||||
old_name, st_mode, patch->old_mode);
|
||||
if (!patch->new_mode)
|
||||
patch->new_mode = st_mode;
|
||||
return 0;
|
||||
|
||||
is_new:
|
||||
|
@ -681,8 +681,8 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
|
||||
argv++;
|
||||
argc--;
|
||||
|
||||
new.name = arg;
|
||||
if ((new.commit = lookup_commit_reference_gently(rev, 1))) {
|
||||
new.name = arg;
|
||||
setup_branch_path(&new);
|
||||
if (resolve_ref(new.path, rev, 1, NULL))
|
||||
new.commit = lookup_commit_reference(rev);
|
||||
|
@ -624,7 +624,6 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
|
||||
if (!commitable && !in_merge && !allow_empty &&
|
||||
!(amend && is_a_merge(head_sha1))) {
|
||||
run_status(stdout, index_file, prefix, 0);
|
||||
unlink(commit_editmsg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -158,7 +158,7 @@ static void display_name(struct commit_name *n)
|
||||
n->tag = lookup_tag(n->sha1);
|
||||
if (!n->tag || parse_tag(n->tag) || !n->tag->tag)
|
||||
die("annotated tag %s not available", n->path);
|
||||
if (strcmp(n->tag->tag, n->path))
|
||||
if (strcmp(n->tag->tag, all ? n->path + 5 : n->path))
|
||||
warning("tag '%s' is really '%s' here", n->tag->tag, n->path);
|
||||
}
|
||||
|
||||
|
@ -497,6 +497,9 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
if (argc == 1)
|
||||
usage_with_options (fast_export_usage, options);
|
||||
|
||||
/* we handle encodings */
|
||||
git_config(git_default_config, NULL);
|
||||
|
||||
|
@ -628,7 +628,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
|
||||
}
|
||||
|
||||
heads = 0;
|
||||
for (i = 1; i < argc; i++) {
|
||||
for (i = 0; i < argc; i++) {
|
||||
const char *arg = argv[i];
|
||||
if (!get_sha1(arg, head_sha1)) {
|
||||
struct object *obj = lookup_object(head_sha1);
|
||||
|
@ -944,6 +944,13 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
||||
* get_revision() to do the usual traversal.
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
* We cannot move this anywhere earlier because we do want to
|
||||
* know if --root was given explicitly from the comand line.
|
||||
*/
|
||||
rev.show_root_diff = 1;
|
||||
|
||||
if (cover_letter) {
|
||||
/* remember the range */
|
||||
int i;
|
||||
|
@ -51,8 +51,11 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix)
|
||||
argc = parse_options(argc, argv, options, merge_file_usage, 0);
|
||||
if (argc != 3)
|
||||
usage_with_options(merge_file_usage, options);
|
||||
if (quiet)
|
||||
freopen("/dev/null", "w", stderr);
|
||||
if (quiet) {
|
||||
if (!freopen("/dev/null", "w", stderr))
|
||||
return error("failed to redirect stderr to /dev/null: "
|
||||
"%s\n", strerror(errno));
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (!names[i])
|
||||
|
@ -192,6 +192,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
|
||||
memmove(destination + i,
|
||||
destination + i + 1,
|
||||
(argc - i) * sizeof(char *));
|
||||
i--;
|
||||
}
|
||||
} else
|
||||
die ("%s, source=%s, destination=%s",
|
||||
|
@ -29,6 +29,9 @@ static int compare_by_number(const void *a1, const void *a2)
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *format_subject(struct strbuf *sb, const char *msg,
|
||||
const char *line_separator);
|
||||
|
||||
static void insert_one_record(struct shortlog *log,
|
||||
const char *author,
|
||||
const char *oneline)
|
||||
@ -41,6 +44,7 @@ static void insert_one_record(struct shortlog *log,
|
||||
size_t len;
|
||||
const char *eol;
|
||||
const char *boemail, *eoemail;
|
||||
struct strbuf subject = STRBUF_INIT;
|
||||
|
||||
boemail = strchr(author, '<');
|
||||
if (!boemail)
|
||||
@ -89,9 +93,8 @@ static void insert_one_record(struct shortlog *log,
|
||||
while (*oneline && isspace(*oneline) && *oneline != '\n')
|
||||
oneline++;
|
||||
len = eol - oneline;
|
||||
while (len && isspace(oneline[len-1]))
|
||||
len--;
|
||||
buffer = xmemdupz(oneline, len);
|
||||
format_subject(&subject, oneline, " ");
|
||||
buffer = strbuf_detach(&subject, NULL);
|
||||
|
||||
if (dot3) {
|
||||
int dot3len = strlen(dot3);
|
||||
|
@ -127,7 +127,7 @@ else
|
||||
SAVE_LDFLAGS="${LDFLAGS}"
|
||||
LDFLAGS="${SAVE_LDFLAGS} -Wl,-rpath,/"
|
||||
AC_LINK_IFELSE(AC_LANG_PROGRAM([], []), [ld_wl_rpath=yes], [ld_wl_rpath=no])
|
||||
LDFLAGS="${SAVE_LD_FLAGS}"
|
||||
LDFLAGS="${SAVE_LDFLAGS}"
|
||||
])
|
||||
if test "$ld_wl_rpath" = "yes"; then
|
||||
AC_SUBST(CC_LD_DYNPATH, [-Wl,-rpath,])
|
||||
@ -136,7 +136,7 @@ else
|
||||
SAVE_LDFLAGS="${LDFLAGS}"
|
||||
LDFLAGS="${SAVE_LDFLAGS} -rpath /"
|
||||
AC_LINK_IFELSE(AC_LANG_PROGRAM([], []), [ld_rpath=yes], [ld_rpath=no])
|
||||
LDFLAGS="${SAVE_LD_FLAGS}"
|
||||
LDFLAGS="${SAVE_LDFLAGS}"
|
||||
])
|
||||
if test "$ld_rpath" = "yes"; then
|
||||
AC_SUBST(CC_LD_DYNPATH, [-rpath])
|
||||
|
3
contrib/examples/README
Normal file
3
contrib/examples/README
Normal file
@ -0,0 +1,3 @@
|
||||
These are original scripted implementations, kept primarily for their
|
||||
reference value to any aspiring plumbing users who want to learn how
|
||||
pieces can be fit together.
|
56
daemon.c
56
daemon.c
@ -150,7 +150,6 @@ static char *path_ok(char *directory)
|
||||
{
|
||||
static char rpath[PATH_MAX];
|
||||
static char interp_path[PATH_MAX];
|
||||
int retried_path = 0;
|
||||
char *path;
|
||||
char *dir;
|
||||
|
||||
@ -219,22 +218,15 @@ static char *path_ok(char *directory)
|
||||
dir = rpath;
|
||||
}
|
||||
|
||||
do {
|
||||
path = enter_repo(dir, strict_paths);
|
||||
if (path)
|
||||
break;
|
||||
|
||||
path = enter_repo(dir, strict_paths);
|
||||
if (!path && base_path && base_path_relaxed) {
|
||||
/*
|
||||
* if we fail and base_path_relaxed is enabled, try without
|
||||
* prefixing the base path
|
||||
*/
|
||||
if (base_path && base_path_relaxed && !retried_path) {
|
||||
dir = directory;
|
||||
retried_path = 1;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
} while (1);
|
||||
dir = directory;
|
||||
path = enter_repo(dir, strict_paths);
|
||||
}
|
||||
|
||||
if (!path) {
|
||||
logerror("'%s': unable to chdir or not a git archive", dir);
|
||||
@ -405,6 +397,14 @@ static void make_service_overridable(const char *name, int ena)
|
||||
die("No such service %s", name);
|
||||
}
|
||||
|
||||
static char *xstrdup_tolower(const char *str)
|
||||
{
|
||||
char *p, *dup = xstrdup(str);
|
||||
for (p = dup; *p; p++)
|
||||
*p = tolower(*p);
|
||||
return dup;
|
||||
}
|
||||
|
||||
/*
|
||||
* Separate the "extra args" information as supplied by the client connection.
|
||||
*/
|
||||
@ -413,7 +413,6 @@ static void parse_extra_args(char *extra_args, int buflen)
|
||||
char *val;
|
||||
int vallen;
|
||||
char *end = extra_args + buflen;
|
||||
char *hp;
|
||||
|
||||
while (extra_args < end && *extra_args) {
|
||||
saw_extended_args = 1;
|
||||
@ -431,7 +430,7 @@ static void parse_extra_args(char *extra_args, int buflen)
|
||||
tcp_port = xstrdup(port);
|
||||
}
|
||||
free(hostname);
|
||||
hostname = xstrdup(host);
|
||||
hostname = xstrdup_tolower(host);
|
||||
}
|
||||
|
||||
/* On to the next one */
|
||||
@ -439,20 +438,11 @@ static void parse_extra_args(char *extra_args, int buflen)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Replace literal host with lowercase-ized hostname.
|
||||
*/
|
||||
hp = hostname;
|
||||
if (!hp)
|
||||
return;
|
||||
for ( ; *hp; hp++)
|
||||
*hp = tolower(*hp);
|
||||
|
||||
/*
|
||||
* Locate canonical hostname and its IP address.
|
||||
*/
|
||||
if (hostname) {
|
||||
#ifndef NO_IPV6
|
||||
{
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *ai, *ai0;
|
||||
int gai;
|
||||
@ -476,9 +466,7 @@ static void parse_extra_args(char *extra_args, int buflen)
|
||||
}
|
||||
freeaddrinfo(ai0);
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
struct hostent *hent;
|
||||
struct sockaddr_in sa;
|
||||
char **ap;
|
||||
@ -499,8 +487,8 @@ static void parse_extra_args(char *extra_args, int buflen)
|
||||
canon_hostname = xstrdup(hent->h_name);
|
||||
free(ip_address);
|
||||
ip_address = xstrdup(addrbuf);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -953,12 +941,8 @@ int main(int argc, char **argv)
|
||||
char *arg = argv[i];
|
||||
|
||||
if (!prefixcmp(arg, "--listen=")) {
|
||||
char *p = arg + 9;
|
||||
char *ph = listen_addr = xmalloc(strlen(arg + 9) + 1);
|
||||
while (*p)
|
||||
*ph++ = tolower(*p++);
|
||||
*ph = 0;
|
||||
continue;
|
||||
listen_addr = xstrdup_tolower(arg + 9);
|
||||
continue;
|
||||
}
|
||||
if (!prefixcmp(arg, "--port=")) {
|
||||
char *end;
|
||||
@ -1118,7 +1102,9 @@ int main(int argc, char **argv)
|
||||
struct sockaddr *peer = (struct sockaddr *)&ss;
|
||||
socklen_t slen = sizeof(ss);
|
||||
|
||||
freopen("/dev/null", "w", stderr);
|
||||
if (!freopen("/dev/null", "w", stderr))
|
||||
die("failed to redirect stderr to /dev/null: %s",
|
||||
strerror(errno));
|
||||
|
||||
if (getpeername(0, peer, &slen))
|
||||
peer = NULL;
|
||||
|
@ -173,8 +173,10 @@ void diff_no_index(struct rev_info *revs,
|
||||
|
||||
/* Were we asked to do --no-index explicitly? */
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (!strcmp(argv[i], "--"))
|
||||
return;
|
||||
if (!strcmp(argv[i], "--")) {
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
if (!strcmp(argv[i], "--no-index"))
|
||||
no_index = 1;
|
||||
if (argv[i][0] != '-')
|
||||
@ -198,13 +200,6 @@ void diff_no_index(struct rev_info *revs,
|
||||
die("git diff %s takes two paths",
|
||||
no_index ? "--no-index" : "[--no-index]");
|
||||
|
||||
/*
|
||||
* If the user asked for our exit code then don't start a
|
||||
* pager or we would end up reporting its exit code instead.
|
||||
*/
|
||||
if (!DIFF_OPT_TST(&revs->diffopt, EXIT_WITH_STATUS))
|
||||
setup_pager();
|
||||
|
||||
diff_setup(&revs->diffopt);
|
||||
if (!revs->diffopt.output_format)
|
||||
revs->diffopt.output_format = DIFF_FORMAT_PATCH;
|
||||
@ -212,8 +207,12 @@ void diff_no_index(struct rev_info *revs,
|
||||
int j;
|
||||
if (!strcmp(argv[i], "--no-index"))
|
||||
i++;
|
||||
else if (!strcmp(argv[1], "-q"))
|
||||
else if (!strcmp(argv[i], "-q")) {
|
||||
options |= DIFF_SILENT_ON_REMOVED;
|
||||
i++;
|
||||
}
|
||||
else if (!strcmp(argv[i], "--"))
|
||||
i++;
|
||||
else {
|
||||
j = diff_opt_parse(&revs->diffopt, argv + i, argc - i);
|
||||
if (!j)
|
||||
@ -222,6 +221,13 @@ void diff_no_index(struct rev_info *revs,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If the user asked for our exit code then don't start a
|
||||
* pager or we would end up reporting its exit code instead.
|
||||
*/
|
||||
if (!DIFF_OPT_TST(&revs->diffopt, EXIT_WITH_STATUS))
|
||||
setup_pager();
|
||||
|
||||
if (prefix) {
|
||||
int len = strlen(prefix);
|
||||
|
||||
|
4
diff.c
4
diff.c
@ -118,7 +118,9 @@ int git_diff_basic_config(const char *var, const char *value, void *cb)
|
||||
}
|
||||
|
||||
/* like GNU diff's --suppress-blank-empty option */
|
||||
if (!strcmp(var, "diff.suppress-blank-empty")) {
|
||||
if (!strcmp(var, "diff.suppressblankempty") ||
|
||||
/* for backwards compatibility */
|
||||
!strcmp(var, "diff.suppress-blank-empty")) {
|
||||
diff_suppress_blank_empty = git_config_bool(var, value);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1872,12 +1872,13 @@ static void file_change_m(struct branch *b)
|
||||
if (!p)
|
||||
die("Corrupt mode: %s", command_buf.buf);
|
||||
switch (mode) {
|
||||
case 0644:
|
||||
case 0755:
|
||||
mode |= S_IFREG;
|
||||
case S_IFREG | 0644:
|
||||
case S_IFREG | 0755:
|
||||
case S_IFLNK:
|
||||
case S_IFGITLINK:
|
||||
case 0644:
|
||||
case 0755:
|
||||
/* ok */
|
||||
break;
|
||||
default:
|
||||
@ -1944,7 +1945,7 @@ static void file_change_m(struct branch *b)
|
||||
typename(type), command_buf.buf);
|
||||
}
|
||||
|
||||
tree_content_set(&b->branch_tree, p, sha1, S_IFREG | mode, NULL);
|
||||
tree_content_set(&b->branch_tree, p, sha1, mode, NULL);
|
||||
}
|
||||
|
||||
static void file_change_d(struct branch *b)
|
||||
|
@ -508,7 +508,7 @@ bisect_visualize() {
|
||||
|
||||
if test $# = 0
|
||||
then
|
||||
case "${DISPLAY+set}${MSYSTEM+set}${SECURITYSESSIONID+set}" in
|
||||
case "${DISPLAY+set}${SESSIONNAME+set}${MSYSTEM+set}${SECURITYSESSIONID+set}" in
|
||||
'') set git log ;;
|
||||
set*) set gitk ;;
|
||||
esac
|
||||
|
@ -349,7 +349,7 @@ do_next () {
|
||||
squash|s)
|
||||
comment_for_reflog squash
|
||||
|
||||
has_action "$DONE" ||
|
||||
test -f "$DONE" && has_action "$DONE" ||
|
||||
die "Cannot 'squash' without a previous commit"
|
||||
|
||||
mark_action_done
|
||||
|
@ -2147,8 +2147,9 @@ sub git_get_projects_list {
|
||||
|
||||
my $subdir = substr($File::Find::name, $pfxlen + 1);
|
||||
# we check related file in $projectroot
|
||||
if (check_export_ok("$projectroot/$filter/$subdir")) {
|
||||
push @list, { path => ($filter ? "$filter/" : '') . $subdir };
|
||||
my $path = ($filter ? "$filter/" : '') . $subdir;
|
||||
if (check_export_ok("$projectroot/$path")) {
|
||||
push @list, { path => $path };
|
||||
$File::Find::prune = 1;
|
||||
}
|
||||
},
|
||||
|
36
http-push.c
36
http-push.c
@ -87,6 +87,7 @@ static struct object_list *objects;
|
||||
struct repo
|
||||
{
|
||||
char *url;
|
||||
char *path;
|
||||
int path_len;
|
||||
int has_info_refs;
|
||||
int can_update_info_refs;
|
||||
@ -1200,7 +1201,8 @@ static struct remote_lock *lock_remote(const char *path, long timeout)
|
||||
/* Make sure leading directories exist for the remote ref */
|
||||
ep = strchr(url + strlen(remote->url) + 1, '/');
|
||||
while (ep) {
|
||||
*ep = 0;
|
||||
char saved_character = ep[1];
|
||||
ep[1] = '\0';
|
||||
slot = get_active_slot();
|
||||
slot->results = &results;
|
||||
curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
|
||||
@ -1222,7 +1224,7 @@ static struct remote_lock *lock_remote(const char *path, long timeout)
|
||||
free(url);
|
||||
return NULL;
|
||||
}
|
||||
*ep = '/';
|
||||
ep[1] = saved_character;
|
||||
ep = strchr(ep + 1, '/');
|
||||
}
|
||||
|
||||
@ -1424,9 +1426,17 @@ static void handle_remote_ls_ctx(struct xml_ctx *ctx, int tag_closed)
|
||||
ls->userFunc(ls);
|
||||
}
|
||||
} else if (!strcmp(ctx->name, DAV_PROPFIND_NAME) && ctx->cdata) {
|
||||
ls->dentry_name = xmalloc(strlen(ctx->cdata) -
|
||||
remote->path_len + 1);
|
||||
strcpy(ls->dentry_name, ctx->cdata + remote->path_len);
|
||||
char *path = ctx->cdata;
|
||||
if (*ctx->cdata == 'h') {
|
||||
path = strstr(path, "//");
|
||||
if (path) {
|
||||
path = strchr(path+2, '/');
|
||||
}
|
||||
}
|
||||
if (path) {
|
||||
path += remote->path_len;
|
||||
ls->dentry_name = xstrdup(path);
|
||||
}
|
||||
} else if (!strcmp(ctx->name, DAV_PROPFIND_COLLECTION)) {
|
||||
ls->dentry_flags |= IS_DIR;
|
||||
}
|
||||
@ -1437,6 +1447,12 @@ static void handle_remote_ls_ctx(struct xml_ctx *ctx, int tag_closed)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* NEEDSWORK: remote_ls() ignores info/refs on the remote side. But it
|
||||
* should _only_ heed the information from that file, instead of trying to
|
||||
* determine the refs from the remote file system (badly: it does not even
|
||||
* know about packed-refs).
|
||||
*/
|
||||
static void remote_ls(const char *path, int flags,
|
||||
void (*userFunc)(struct remote_ls_ctx *ls),
|
||||
void *userData)
|
||||
@ -2206,10 +2222,11 @@ int main(int argc, char **argv)
|
||||
if (!remote->url) {
|
||||
char *path = strstr(arg, "//");
|
||||
remote->url = arg;
|
||||
remote->path_len = strlen(arg);
|
||||
if (path) {
|
||||
path = strchr(path+2, '/');
|
||||
if (path)
|
||||
remote->path_len = strlen(path);
|
||||
remote->path = strchr(path+2, '/');
|
||||
if (remote->path)
|
||||
remote->path_len = strlen(remote->path);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@ -2238,8 +2255,9 @@ int main(int argc, char **argv)
|
||||
rewritten_url = xmalloc(strlen(remote->url)+2);
|
||||
strcpy(rewritten_url, remote->url);
|
||||
strcat(rewritten_url, "/");
|
||||
remote->path = rewritten_url + (remote->path - remote->url);
|
||||
remote->path_len++;
|
||||
remote->url = rewritten_url;
|
||||
++remote->path_len;
|
||||
}
|
||||
|
||||
/* Verify DAV compliance/lock support */
|
||||
|
@ -447,6 +447,30 @@ static void flush_buffer(int fd, const char *buf, unsigned long size)
|
||||
}
|
||||
}
|
||||
|
||||
static int would_lose_untracked(const char *path)
|
||||
{
|
||||
int pos = cache_name_pos(path, strlen(path));
|
||||
|
||||
if (pos < 0)
|
||||
pos = -1 - pos;
|
||||
while (pos < active_nr &&
|
||||
!strcmp(path, active_cache[pos]->name)) {
|
||||
/*
|
||||
* If stage #0, it is definitely tracked.
|
||||
* If it has stage #2 then it was tracked
|
||||
* before this merge started. All other
|
||||
* cases the path was not tracked.
|
||||
*/
|
||||
switch (ce_stage(active_cache[pos])) {
|
||||
case 0:
|
||||
case 2:
|
||||
return 0;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
return file_exists(path);
|
||||
}
|
||||
|
||||
static int make_room_for_path(const char *path)
|
||||
{
|
||||
int status;
|
||||
@ -462,6 +486,14 @@ static int make_room_for_path(const char *path)
|
||||
die(msg, path, "");
|
||||
}
|
||||
|
||||
/*
|
||||
* Do not unlink a file in the work tree if we are not
|
||||
* tracking it.
|
||||
*/
|
||||
if (would_lose_untracked(path))
|
||||
return error("refusing to lose untracked file at '%s'",
|
||||
path);
|
||||
|
||||
/* Successful unlink is good.. */
|
||||
if (!unlink(path))
|
||||
return 0;
|
||||
@ -902,6 +934,11 @@ static int process_renames(struct merge_options *o,
|
||||
ren1_src, ren1_dst, branch1,
|
||||
branch2);
|
||||
update_file(o, 0, ren1->pair->two->sha1, ren1->pair->two->mode, ren1_dst);
|
||||
update_stages(ren1_dst, NULL,
|
||||
branch1 == o->branch1 ?
|
||||
ren1->pair->two : NULL,
|
||||
branch1 == o->branch1 ?
|
||||
NULL : ren1->pair->two, 1);
|
||||
} else if (!sha_eq(dst_other.sha1, null_sha1)) {
|
||||
const char *new_path;
|
||||
clean_merge = 0;
|
||||
|
11
perl/Git.pm
11
perl/Git.pm
@ -166,11 +166,12 @@ sub repository {
|
||||
}
|
||||
}
|
||||
|
||||
if (not defined $opts{Repository} and not defined $opts{WorkingCopy}) {
|
||||
$opts{Directory} ||= '.';
|
||||
if (not defined $opts{Repository} and not defined $opts{WorkingCopy}
|
||||
and not defined $opts{Directory}) {
|
||||
$opts{Directory} = '.';
|
||||
}
|
||||
|
||||
if ($opts{Directory}) {
|
||||
if (defined $opts{Directory}) {
|
||||
-d $opts{Directory} or throw Error::Simple("Directory not found: $!");
|
||||
|
||||
my $search = Git->repository(WorkingCopy => $opts{Directory});
|
||||
@ -1010,8 +1011,8 @@ sub _temp_cache {
|
||||
my $temp_fd = \$TEMP_FILEMAP{$name};
|
||||
if (defined $$temp_fd and $$temp_fd->opened) {
|
||||
if ($TEMP_FILES{$$temp_fd}{locked}) {
|
||||
throw Error::Simple("Temp file with moniker '",
|
||||
$name, "' already in use");
|
||||
throw Error::Simple("Temp file with moniker '" .
|
||||
$name . "' already in use");
|
||||
}
|
||||
} else {
|
||||
if (defined $$temp_fd) {
|
||||
|
119
pretty.c
119
pretty.c
@ -181,6 +181,20 @@ static int is_empty_line(const char *line, int *len_p)
|
||||
return !len;
|
||||
}
|
||||
|
||||
static const char *skip_empty_lines(const char *msg)
|
||||
{
|
||||
for (;;) {
|
||||
int linelen = get_one_line(msg);
|
||||
int ll = linelen;
|
||||
if (!linelen)
|
||||
break;
|
||||
if (!is_empty_line(msg, &ll))
|
||||
break;
|
||||
msg += linelen;
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
static void add_merge_info(enum cmit_fmt fmt, struct strbuf *sb,
|
||||
const struct commit *commit, int abbrev)
|
||||
{
|
||||
@ -410,13 +424,15 @@ struct chunk {
|
||||
struct format_commit_context {
|
||||
const struct commit *commit;
|
||||
enum date_mode dmode;
|
||||
unsigned commit_header_parsed:1;
|
||||
unsigned commit_message_parsed:1;
|
||||
|
||||
/* These offsets are relative to the start of the commit message. */
|
||||
int commit_header_parsed;
|
||||
struct chunk subject;
|
||||
struct chunk author;
|
||||
struct chunk committer;
|
||||
struct chunk encoding;
|
||||
size_t message_off;
|
||||
size_t subject_off;
|
||||
size_t body_off;
|
||||
|
||||
/* The following ones are relative to the result struct strbuf. */
|
||||
@ -446,23 +462,14 @@ static void parse_commit_header(struct format_commit_context *context)
|
||||
{
|
||||
const char *msg = context->commit->buffer;
|
||||
int i;
|
||||
enum { HEADER, SUBJECT, BODY } state;
|
||||
|
||||
for (i = 0, state = HEADER; msg[i] && state < BODY; i++) {
|
||||
for (i = 0; msg[i]; i++) {
|
||||
int eol;
|
||||
for (eol = i; msg[eol] && msg[eol] != '\n'; eol++)
|
||||
; /* do nothing */
|
||||
|
||||
if (state == SUBJECT) {
|
||||
context->subject.off = i;
|
||||
context->subject.len = eol - i;
|
||||
i = eol;
|
||||
}
|
||||
if (i == eol) {
|
||||
state++;
|
||||
/* strip empty lines */
|
||||
while (msg[eol] == '\n' && msg[eol + 1] == '\n')
|
||||
eol++;
|
||||
break;
|
||||
} else if (!prefixcmp(msg + i, "author ")) {
|
||||
context->author.off = i + 7;
|
||||
context->author.len = eol - i - 7;
|
||||
@ -474,13 +481,50 @@ static void parse_commit_header(struct format_commit_context *context)
|
||||
context->encoding.len = eol - i - 9;
|
||||
}
|
||||
i = eol;
|
||||
if (!msg[i])
|
||||
break;
|
||||
}
|
||||
context->body_off = i;
|
||||
context->message_off = i;
|
||||
context->commit_header_parsed = 1;
|
||||
}
|
||||
|
||||
const char *format_subject(struct strbuf *sb, const char *msg,
|
||||
const char *line_separator)
|
||||
{
|
||||
int first = 1;
|
||||
|
||||
for (;;) {
|
||||
const char *line = msg;
|
||||
int linelen = get_one_line(line);
|
||||
|
||||
msg += linelen;
|
||||
if (!linelen || is_empty_line(line, &linelen))
|
||||
break;
|
||||
|
||||
if (!sb)
|
||||
continue;
|
||||
strbuf_grow(sb, linelen + 2);
|
||||
if (!first)
|
||||
strbuf_addstr(sb, line_separator);
|
||||
strbuf_add(sb, line, linelen);
|
||||
first = 0;
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
static void parse_commit_message(struct format_commit_context *c)
|
||||
{
|
||||
const char *msg = c->commit->buffer + c->message_off;
|
||||
const char *start = c->commit->buffer;
|
||||
|
||||
msg = skip_empty_lines(msg);
|
||||
c->subject_off = msg - start;
|
||||
|
||||
msg = format_subject(NULL, msg, NULL);
|
||||
msg = skip_empty_lines(msg);
|
||||
c->body_off = msg - start;
|
||||
|
||||
c->commit_message_parsed = 1;
|
||||
}
|
||||
|
||||
static void format_decoration(struct strbuf *sb, const struct commit *commit)
|
||||
{
|
||||
struct name_decoration *d;
|
||||
@ -600,9 +644,6 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
|
||||
parse_commit_header(c);
|
||||
|
||||
switch (placeholder[0]) {
|
||||
case 's': /* subject */
|
||||
strbuf_add(sb, msg + c->subject.off, c->subject.len);
|
||||
return 1;
|
||||
case 'a': /* author ... */
|
||||
return format_person_part(sb, placeholder[1],
|
||||
msg + c->author.off, c->author.len,
|
||||
@ -614,6 +655,16 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
|
||||
case 'e': /* encoding */
|
||||
strbuf_add(sb, msg + c->encoding.off, c->encoding.len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Now we need to parse the commit message. */
|
||||
if (!c->commit_message_parsed)
|
||||
parse_commit_message(c);
|
||||
|
||||
switch (placeholder[0]) {
|
||||
case 's': /* subject */
|
||||
format_subject(sb, msg + c->subject_off, " ");
|
||||
return 1;
|
||||
case 'b': /* body */
|
||||
strbuf_addstr(sb, msg + c->body_off);
|
||||
return 1;
|
||||
@ -704,27 +755,11 @@ void pp_title_line(enum cmit_fmt fmt,
|
||||
const char *encoding,
|
||||
int need_8bit_cte)
|
||||
{
|
||||
const char *line_separator = (fmt == CMIT_FMT_EMAIL) ? "\n " : " ";
|
||||
struct strbuf title;
|
||||
|
||||
strbuf_init(&title, 80);
|
||||
|
||||
for (;;) {
|
||||
const char *line = *msg_p;
|
||||
int linelen = get_one_line(line);
|
||||
|
||||
*msg_p += linelen;
|
||||
if (!linelen || is_empty_line(line, &linelen))
|
||||
break;
|
||||
|
||||
strbuf_grow(&title, linelen + 2);
|
||||
if (title.len) {
|
||||
if (fmt == CMIT_FMT_EMAIL) {
|
||||
strbuf_addch(&title, '\n');
|
||||
}
|
||||
strbuf_addch(&title, ' ');
|
||||
}
|
||||
strbuf_add(&title, line, linelen);
|
||||
}
|
||||
*msg_p = format_subject(&title, *msg_p, line_separator);
|
||||
|
||||
strbuf_grow(sb, title.len + 1024);
|
||||
if (subject) {
|
||||
@ -850,15 +885,7 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
|
||||
}
|
||||
|
||||
/* Skip excess blank lines at the beginning of body, if any... */
|
||||
for (;;) {
|
||||
int linelen = get_one_line(msg);
|
||||
int ll = linelen;
|
||||
if (!linelen)
|
||||
break;
|
||||
if (!is_empty_line(msg, &ll))
|
||||
break;
|
||||
msg += linelen;
|
||||
}
|
||||
msg = skip_empty_lines(msg);
|
||||
|
||||
/* These formats treat the title line specially. */
|
||||
if (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL)
|
||||
|
@ -1,6 +1,8 @@
|
||||
ServerName dummy
|
||||
PidFile httpd.pid
|
||||
DocumentRoot www
|
||||
LogFormat "%h %l %u %t \"%r\" %>s %b" common
|
||||
CustomLog access.log common
|
||||
ErrorLog error.log
|
||||
|
||||
<IfDefine SSL>
|
||||
|
@ -341,4 +341,55 @@ test_expect_success \
|
||||
check_cache_at DF/DF dirty &&
|
||||
:'
|
||||
|
||||
test_expect_success \
|
||||
'a/b (untracked) vs a case setup.' \
|
||||
'rm -f .git/index &&
|
||||
: >a &&
|
||||
git update-index --add a &&
|
||||
treeM=`git write-tree` &&
|
||||
echo treeM $treeM &&
|
||||
git ls-tree $treeM &&
|
||||
git ls-files --stage >treeM.out &&
|
||||
|
||||
rm -f a &&
|
||||
git update-index --remove a &&
|
||||
mkdir a &&
|
||||
: >a/b &&
|
||||
treeH=`git write-tree` &&
|
||||
echo treeH $treeH &&
|
||||
git ls-tree $treeH'
|
||||
|
||||
test_expect_success \
|
||||
'a/b (untracked) vs a, plus c/d case test.' \
|
||||
'! git read-tree -u -m "$treeH" "$treeM" &&
|
||||
git ls-files --stage &&
|
||||
test -f a/b'
|
||||
|
||||
test_expect_success \
|
||||
'a/b vs a, plus c/d case setup.' \
|
||||
'rm -f .git/index &&
|
||||
rm -fr a &&
|
||||
: >a &&
|
||||
mkdir c &&
|
||||
: >c/d &&
|
||||
git update-index --add a c/d &&
|
||||
treeM=`git write-tree` &&
|
||||
echo treeM $treeM &&
|
||||
git ls-tree $treeM &&
|
||||
git ls-files --stage >treeM.out &&
|
||||
|
||||
rm -f a &&
|
||||
mkdir a
|
||||
: >a/b &&
|
||||
git update-index --add --remove a a/b &&
|
||||
treeH=`git write-tree` &&
|
||||
echo treeH $treeH &&
|
||||
git ls-tree $treeH'
|
||||
|
||||
test_expect_success \
|
||||
'a/b vs a, plus c/d case test.' \
|
||||
'git read-tree -u -m "$treeH" "$treeM" &&
|
||||
git ls-files --stage | tee >treeMcheck.out &&
|
||||
test_cmp treeM.out treeMcheck.out'
|
||||
|
||||
test_done
|
||||
|
@ -10,6 +10,10 @@ test_expect_success 'setup' '
|
||||
git commit -m initial
|
||||
'
|
||||
|
||||
test_expect_success 'checkout should not start branch from a tree' '
|
||||
test_must_fail git checkout -b newbranch master^{tree}
|
||||
'
|
||||
|
||||
test_expect_success 'checkout master from invalid HEAD' '
|
||||
echo 0000000000000000000000000000000000000000 >.git/HEAD &&
|
||||
git checkout master --
|
||||
|
@ -373,6 +373,38 @@ test_expect_success '--continue tries to commit, even for "edit"' '
|
||||
test $parent = $(git rev-parse HEAD^)
|
||||
'
|
||||
|
||||
test_expect_success 'aborted --continue does not squash commits after "edit"' '
|
||||
old=$(git rev-parse HEAD) &&
|
||||
test_tick &&
|
||||
FAKE_LINES="edit 1" git rebase -i HEAD^ &&
|
||||
echo "edited again" > file7 &&
|
||||
git add file7 &&
|
||||
(
|
||||
FAKE_COMMIT_MESSAGE=" " &&
|
||||
export FAKE_COMMIT_MESSAGE &&
|
||||
test_must_fail git rebase --continue
|
||||
) &&
|
||||
test $old = $(git rev-parse HEAD) &&
|
||||
git rebase --abort
|
||||
'
|
||||
|
||||
test_expect_success 'auto-amend only edited commits after "edit"' '
|
||||
test_tick &&
|
||||
FAKE_LINES="edit 1" git rebase -i HEAD^ &&
|
||||
echo "edited again" > file7 &&
|
||||
git add file7 &&
|
||||
FAKE_COMMIT_MESSAGE="edited file7 again" git commit &&
|
||||
echo "and again" > file7 &&
|
||||
git add file7 &&
|
||||
test_tick &&
|
||||
(
|
||||
FAKE_COMMIT_MESSAGE="and again" &&
|
||||
export FAKE_COMMIT_MESSAGE &&
|
||||
test_must_fail git rebase --continue
|
||||
) &&
|
||||
git rebase --abort
|
||||
'
|
||||
|
||||
test_expect_success 'rebase a detached HEAD' '
|
||||
grandparent=$(git rev-parse HEAD~2) &&
|
||||
git checkout $(git rev-parse HEAD) &&
|
||||
|
0
t/t3411-rebase-preserve-around-merges.sh
Normal file → Executable file
0
t/t3411-rebase-preserve-around-merges.sh
Normal file → Executable file
@ -45,6 +45,7 @@ test_expect_success 'cherry-pick after renaming branch' '
|
||||
|
||||
git checkout rename2 &&
|
||||
git cherry-pick added &&
|
||||
test $(git rev-parse HEAD^) = $(git rev-parse rename2) &&
|
||||
test -f opos &&
|
||||
grep "Add extra line at the end" opos
|
||||
|
||||
@ -54,6 +55,7 @@ test_expect_success 'revert after renaming branch' '
|
||||
|
||||
git checkout rename1 &&
|
||||
git revert added &&
|
||||
test $(git rev-parse HEAD^) = $(git rev-parse rename1) &&
|
||||
test -f spoo &&
|
||||
! grep "Add extra line at the end" spoo
|
||||
|
||||
|
@ -261,6 +261,7 @@ diff --patch-with-stat -r initial..side
|
||||
diff --patch-with-raw -r initial..side
|
||||
diff --name-status dir2 dir
|
||||
diff --no-index --name-status dir2 dir
|
||||
diff --no-index --name-status -- dir2 dir
|
||||
diff master master^ side
|
||||
EOF
|
||||
|
||||
|
3
t/t4013/diff.diff_--no-index_--name-status_--_dir2_dir
Normal file
3
t/t4013/diff.diff_--no-index_--name-status_--_dir2_dir
Normal file
@ -0,0 +1,3 @@
|
||||
$ git diff --no-index --name-status -- dir2 dir
|
||||
A dir/sub
|
||||
$
|
@ -2,7 +2,7 @@
|
||||
#
|
||||
# Copyright (c) Jim Meyering
|
||||
#
|
||||
test_description='diff honors config option, diff.suppress-blank-empty'
|
||||
test_description='diff honors config option, diff.suppressBlankEmpty'
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
@ -24,14 +24,14 @@ test_expect_success \
|
||||
git add f &&
|
||||
git commit -q -m. f &&
|
||||
printf "\ny\n" > f &&
|
||||
git config --bool diff.suppress-blank-empty true &&
|
||||
git config --bool diff.suppressBlankEmpty true &&
|
||||
git diff f > actual &&
|
||||
test_cmp exp actual &&
|
||||
perl -i.bak -p -e "s/^\$/ /" exp &&
|
||||
git config --bool diff.suppress-blank-empty false &&
|
||||
git config --bool diff.suppressBlankEmpty false &&
|
||||
git diff f > actual &&
|
||||
test_cmp exp actual &&
|
||||
git config --bool --unset diff.suppress-blank-empty &&
|
||||
git config --bool --unset diff.suppressBlankEmpty &&
|
||||
git diff f > actual &&
|
||||
test_cmp exp actual
|
||||
'
|
||||
|
62
t/t4129-apply-samemode.sh
Executable file
62
t/t4129-apply-samemode.sh
Executable file
@ -0,0 +1,62 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='applying patch with mode bits'
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
test_expect_success setup '
|
||||
echo original >file &&
|
||||
git add file &&
|
||||
test_tick &&
|
||||
git commit -m initial &&
|
||||
git tag initial &&
|
||||
echo modified >file &&
|
||||
git diff --stat -p >patch-0.txt &&
|
||||
chmod +x file &&
|
||||
git diff --stat -p >patch-1.txt
|
||||
'
|
||||
|
||||
test_expect_success 'same mode (no index)' '
|
||||
git reset --hard &&
|
||||
chmod +x file &&
|
||||
git apply patch-0.txt &&
|
||||
test -x file
|
||||
'
|
||||
|
||||
test_expect_success 'same mode (with index)' '
|
||||
git reset --hard &&
|
||||
chmod +x file &&
|
||||
git add file &&
|
||||
git apply --index patch-0.txt &&
|
||||
test -x file &&
|
||||
git diff --exit-code
|
||||
'
|
||||
|
||||
test_expect_success 'same mode (index only)' '
|
||||
git reset --hard &&
|
||||
chmod +x file &&
|
||||
git add file &&
|
||||
git apply --cached patch-0.txt &&
|
||||
git ls-files -s file | grep "^100755"
|
||||
'
|
||||
|
||||
test_expect_success 'mode update (no index)' '
|
||||
git reset --hard &&
|
||||
git apply patch-1.txt &&
|
||||
test -x file
|
||||
'
|
||||
|
||||
test_expect_success 'mode update (with index)' '
|
||||
git reset --hard &&
|
||||
git apply --index patch-1.txt &&
|
||||
test -x file &&
|
||||
git diff --exit-code
|
||||
'
|
||||
|
||||
test_expect_success 'mode update (index only)' '
|
||||
git reset --hard &&
|
||||
git apply --cached patch-1.txt &&
|
||||
git ls-files -s file | grep "^100755"
|
||||
'
|
||||
|
||||
test_done
|
@ -51,17 +51,29 @@ test_expect_success 'clone remote repository' '
|
||||
git clone $HTTPD_URL/test_repo.git test_repo_clone
|
||||
'
|
||||
|
||||
test_expect_failure 'push to remote repository' '
|
||||
test_expect_failure 'push to remote repository with packed refs' '
|
||||
cd "$ROOT_PATH"/test_repo_clone &&
|
||||
: >path2 &&
|
||||
git add path2 &&
|
||||
test_tick &&
|
||||
git commit -m path2 &&
|
||||
HEAD=$(git rev-parse --verify HEAD) &&
|
||||
git push &&
|
||||
[ -f "$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/refs/heads/master" ]
|
||||
(cd "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git &&
|
||||
test $HEAD = $(git rev-parse --verify HEAD))
|
||||
'
|
||||
|
||||
test_expect_failure 'create and delete remote branch' '
|
||||
test_expect_success ' push to remote repository with unpacked refs' '
|
||||
(cd "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git &&
|
||||
rm packed-refs &&
|
||||
git update-ref refs/heads/master \
|
||||
0c973ae9bd51902a28466f3850b543fa66a6aaf4) &&
|
||||
git push &&
|
||||
(cd "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git &&
|
||||
test $HEAD = $(git rev-parse --verify HEAD))
|
||||
'
|
||||
|
||||
test_expect_success 'create and delete remote branch' '
|
||||
cd "$ROOT_PATH"/test_repo_clone &&
|
||||
git checkout -b dev &&
|
||||
: >path3 &&
|
||||
@ -76,6 +88,12 @@ test_expect_failure 'create and delete remote branch' '
|
||||
test_must_fail git show-ref --verify refs/remotes/origin/dev
|
||||
'
|
||||
|
||||
test_expect_success 'MKCOL sends directory names with trailing slashes' '
|
||||
|
||||
! grep "\"MKCOL.*[^/] HTTP/[^ ]*\"" < "$HTTPD_ROOT_PATH"/access.log
|
||||
|
||||
'
|
||||
|
||||
stop_httpd
|
||||
|
||||
test_done
|
||||
|
@ -97,4 +97,27 @@ test_expect_success 'refuse to merge binary files' '
|
||||
merge.err
|
||||
'
|
||||
|
||||
test_expect_success 'mark rename/delete as unmerged' '
|
||||
|
||||
git reset --hard &&
|
||||
git checkout -b delete &&
|
||||
git rm a1 &&
|
||||
test_tick &&
|
||||
git commit -m delete &&
|
||||
git checkout -b rename HEAD^ &&
|
||||
git mv a1 a2
|
||||
test_tick &&
|
||||
git commit -m rename &&
|
||||
test_must_fail git merge delete &&
|
||||
test 1 = $(git ls-files --unmerged | wc -l) &&
|
||||
git rev-parse --verify :2:a2 &&
|
||||
test_must_fail git rev-parse --verify :3:a2 &&
|
||||
git checkout -f delete &&
|
||||
test_must_fail git merge rename &&
|
||||
test 1 = $(git ls-files --unmerged | wc -l) &&
|
||||
test_must_fail git rev-parse --verify :2:a2 &&
|
||||
git rev-parse --verify :3:a2
|
||||
|
||||
'
|
||||
|
||||
test_done
|
||||
|
@ -100,6 +100,12 @@ check_describe B --tags HEAD^^2^
|
||||
check_describe B-0-* --long HEAD^^2^
|
||||
check_describe A-3-* --long HEAD^^2
|
||||
|
||||
: >err.expect
|
||||
check_describe A --all A^0
|
||||
test_expect_success 'no warning was displayed for A' '
|
||||
test_cmp err.expect err.actual
|
||||
'
|
||||
|
||||
test_expect_success 'rename tag A to Q locally' '
|
||||
mv .git/refs/tags/A .git/refs/tags/Q
|
||||
'
|
||||
|
@ -38,6 +38,31 @@ test_expect_success \
|
||||
'git diff-tree -r -M --name-status HEAD^ HEAD | \
|
||||
grep "^R100..*path1/COPYING..*path0/COPYING"'
|
||||
|
||||
test_expect_success \
|
||||
'checking -k on non-existing file' \
|
||||
'git mv -k idontexist path0'
|
||||
|
||||
test_expect_success \
|
||||
'checking -k on untracked file' \
|
||||
'touch untracked1 &&
|
||||
git mv -k untracked1 path0 &&
|
||||
test -f untracked1 &&
|
||||
test ! -f path0/untracked1'
|
||||
|
||||
test_expect_success \
|
||||
'checking -k on multiple untracked files' \
|
||||
'touch untracked2 &&
|
||||
git mv -k untracked1 untracked2 path0 &&
|
||||
test -f untracked1 &&
|
||||
test -f untracked2 &&
|
||||
test ! -f path0/untracked1
|
||||
test ! -f path0/untracked2'
|
||||
|
||||
# clean up the mess in case bad things happen
|
||||
rm -f idontexist untracked1 untracked2 \
|
||||
path0/idontexist path0/untracked1 path0/untracked2 \
|
||||
.git/index.lock
|
||||
|
||||
test_expect_success \
|
||||
'adding another file' \
|
||||
'cp "$TEST_DIRECTORY"/../README path0/README &&
|
||||
|
@ -209,4 +209,29 @@ test_expect_success 'update --init' '
|
||||
|
||||
'
|
||||
|
||||
test_expect_success 'do not add files from a submodule' '
|
||||
|
||||
git reset --hard &&
|
||||
test_must_fail git add init/a
|
||||
|
||||
'
|
||||
|
||||
test_expect_success 'gracefully add submodule with a trailing slash' '
|
||||
|
||||
git reset --hard &&
|
||||
git commit -m "commit subproject" init &&
|
||||
(cd init &&
|
||||
echo b > a) &&
|
||||
git add init/ &&
|
||||
git diff --exit-code --cached init &&
|
||||
commit=$(cd init &&
|
||||
git commit -m update a >/dev/null &&
|
||||
git rev-parse HEAD) &&
|
||||
git add init/ &&
|
||||
test_must_fail git diff --exit-code --cached init &&
|
||||
test $commit = $(git ls-files --stage |
|
||||
sed -n "s/^160000 \([^ ]*\).*/\1/p")
|
||||
|
||||
'
|
||||
|
||||
test_done
|
||||
|
87
t/t7607-merge-overwrite.sh
Executable file
87
t/t7607-merge-overwrite.sh
Executable file
@ -0,0 +1,87 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='git-merge
|
||||
|
||||
Do not overwrite changes.'
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
test_expect_success 'setup' '
|
||||
echo c0 > c0.c &&
|
||||
git add c0.c &&
|
||||
git commit -m c0 &&
|
||||
git tag c0 &&
|
||||
echo c1 > c1.c &&
|
||||
git add c1.c &&
|
||||
git commit -m c1 &&
|
||||
git tag c1 &&
|
||||
git reset --hard c0 &&
|
||||
echo c2 > c2.c &&
|
||||
git add c2.c &&
|
||||
git commit -m c2 &&
|
||||
git tag c2 &&
|
||||
git reset --hard c1 &&
|
||||
echo "c1 a" > c1.c &&
|
||||
git add c1.c &&
|
||||
git commit -m "c1 a" &&
|
||||
git tag c1a &&
|
||||
echo "VERY IMPORTANT CHANGES" > important
|
||||
'
|
||||
|
||||
test_expect_success 'will not overwrite untracked file' '
|
||||
git reset --hard c1 &&
|
||||
cat important > c2.c &&
|
||||
! git merge c2 &&
|
||||
test_cmp important c2.c
|
||||
'
|
||||
|
||||
test_expect_success 'will not overwrite new file' '
|
||||
git reset --hard c1 &&
|
||||
cat important > c2.c &&
|
||||
git add c2.c &&
|
||||
! git merge c2 &&
|
||||
test_cmp important c2.c
|
||||
'
|
||||
|
||||
test_expect_success 'will not overwrite staged changes' '
|
||||
git reset --hard c1 &&
|
||||
cat important > c2.c &&
|
||||
git add c2.c &&
|
||||
rm c2.c &&
|
||||
! git merge c2 &&
|
||||
git checkout c2.c &&
|
||||
test_cmp important c2.c
|
||||
'
|
||||
|
||||
test_expect_success 'will not overwrite removed file' '
|
||||
git reset --hard c1 &&
|
||||
git rm c1.c &&
|
||||
git commit -m "rm c1.c" &&
|
||||
cat important > c1.c &&
|
||||
! git merge c1a &&
|
||||
test_cmp important c1.c
|
||||
'
|
||||
|
||||
test_expect_success 'will not overwrite re-added file' '
|
||||
git reset --hard c1 &&
|
||||
git rm c1.c &&
|
||||
git commit -m "rm c1.c" &&
|
||||
cat important > c1.c &&
|
||||
git add c1.c &&
|
||||
! git merge c1a &&
|
||||
test_cmp important c1.c
|
||||
'
|
||||
|
||||
test_expect_success 'will not overwrite removed file with staged changes' '
|
||||
git reset --hard c1 &&
|
||||
git rm c1.c &&
|
||||
git commit -m "rm c1.c" &&
|
||||
cat important > c1.c &&
|
||||
git add c1.c &&
|
||||
rm c1.c &&
|
||||
! git merge c1a &&
|
||||
git checkout c1.c &&
|
||||
test_cmp important c1.c
|
||||
'
|
||||
|
||||
test_done
|
@ -494,7 +494,7 @@ static int verify_clean_subdirectory(struct cache_entry *ce, const char *action,
|
||||
* anything in the existing directory there.
|
||||
*/
|
||||
int namelen;
|
||||
int pos, i;
|
||||
int i;
|
||||
struct dir_struct d;
|
||||
char *pathbuf;
|
||||
int cnt = 0;
|
||||
@ -515,24 +515,20 @@ static int verify_clean_subdirectory(struct cache_entry *ce, const char *action,
|
||||
* in that directory.
|
||||
*/
|
||||
namelen = strlen(ce->name);
|
||||
pos = index_name_pos(o->src_index, ce->name, namelen);
|
||||
if (0 <= pos)
|
||||
return cnt; /* we have it as nondirectory */
|
||||
pos = -pos - 1;
|
||||
for (i = pos; i < o->src_index->cache_nr; i++) {
|
||||
struct cache_entry *ce = o->src_index->cache[i];
|
||||
int len = ce_namelen(ce);
|
||||
for (i = o->pos; i < o->src_index->cache_nr; i++) {
|
||||
struct cache_entry *ce2 = o->src_index->cache[i];
|
||||
int len = ce_namelen(ce2);
|
||||
if (len < namelen ||
|
||||
strncmp(ce->name, ce->name, namelen) ||
|
||||
ce->name[namelen] != '/')
|
||||
strncmp(ce->name, ce2->name, namelen) ||
|
||||
ce2->name[namelen] != '/')
|
||||
break;
|
||||
/*
|
||||
* ce->name is an entry in the subdirectory.
|
||||
* ce2->name is an entry in the subdirectory.
|
||||
*/
|
||||
if (!ce_stage(ce)) {
|
||||
if (verify_uptodate(ce, o))
|
||||
if (!ce_stage(ce2)) {
|
||||
if (verify_uptodate(ce2, o))
|
||||
return -1;
|
||||
add_entry(o, ce, CE_REMOVE, 0);
|
||||
add_entry(o, ce2, CE_REMOVE, 0);
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
@ -588,7 +584,7 @@ static int verify_absent(struct cache_entry *ce, const char *action,
|
||||
return 0;
|
||||
|
||||
if (!lstat(ce->name, &st)) {
|
||||
int cnt;
|
||||
int ret;
|
||||
int dtype = ce_to_dtype(ce);
|
||||
struct cache_entry *result;
|
||||
|
||||
@ -616,13 +612,15 @@ static int verify_absent(struct cache_entry *ce, const char *action,
|
||||
* files that are in "foo/" we would lose
|
||||
* it.
|
||||
*/
|
||||
cnt = verify_clean_subdirectory(ce, action, o);
|
||||
ret = verify_clean_subdirectory(ce, action, o);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* If this removed entries from the index,
|
||||
* what that means is:
|
||||
*
|
||||
* (1) the caller unpack_trees_rec() saw path/foo
|
||||
* (1) the caller unpack_callback() saw path/foo
|
||||
* in the index, and it has not removed it because
|
||||
* it thinks it is handling 'path' as blob with
|
||||
* D/F conflict;
|
||||
@ -635,7 +633,7 @@ static int verify_absent(struct cache_entry *ce, const char *action,
|
||||
* We need to increment it by the number of
|
||||
* deleted entries here.
|
||||
*/
|
||||
o->pos += cnt;
|
||||
o->pos += ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user