mirror of
https://github.com/git/git
synced 2024-08-27 11:39:22 +00:00
Merge branch 'maint' into bc/master-diff-hunk-header-fix
* maint: (41 commits) Clarify commit error message for unmerged files Use strchrnul() instead of strchr() plus manual workaround Use remove_path from dir.c instead of own implementation Add remove_path: a function to remove as much as possible of a path git-submodule: Fix "Unable to checkout" for the initial 'update' Clarify how the user can satisfy stash's 'dirty state' check. Remove empty directories in recursive merge Documentation: clarify the details of overriding LESS via core.pager Update release notes for 1.6.0.3 checkout: Do not show local changes when in quiet mode for-each-ref: Fix --format=%(subject) for log message without newlines git-stash.sh: don't default to refs/stash if invalid ref supplied maint: check return of split_cmdline to avoid bad config strings builtin-prune.c: prune temporary packs in <object_dir>/pack directory Do not perform cross-directory renames when creating packs Use dashless git commands in setgitperms.perl git-remote: do not use user input in a printf format string make "git remote" report multiple URLs Start draft release notes for 1.6.0.3 git-repack uses --no-repack-object, not --no-repack-delta. ... Conflicts: RelNotes
This commit is contained in:
commit
5a139ba483
45
Documentation/RelNotes-1.6.0.3.txt
Normal file
45
Documentation/RelNotes-1.6.0.3.txt
Normal file
|
@ -0,0 +1,45 @@
|
|||
GIT v1.6.0.3 Release Notes
|
||||
==========================
|
||||
|
||||
Fixes since v1.6.0.2
|
||||
--------------------
|
||||
|
||||
* "git archive --format=zip" did not honor core.autocrlf while
|
||||
--format=tar did.
|
||||
|
||||
* Continuing "git rebase -i" was very confused when the user left modified
|
||||
files in the working tree while resolving conflicts.
|
||||
|
||||
* Continuing "git rebase -i" was also very confused when the user left
|
||||
some staged changes in the index after "edit".
|
||||
|
||||
* Behaviour of "git diff --quiet" was inconsistent with "diff --exit-code"
|
||||
with the output redirected to /dev/null.
|
||||
|
||||
* "git stash apply sash@{1}" was fixed to error out. Prior versions
|
||||
would have applied stash@{0} incorrectly.
|
||||
|
||||
* "git for-each-ref --format=%(subject)" fixed for commits with no
|
||||
no newline in the message body.
|
||||
|
||||
* "git remote" fixed to protect printf from user input.
|
||||
|
||||
* "git checkout -q" once again suppresses the locally modified file list.
|
||||
|
||||
* Cross-directory renames are no longer used when creating packs. This
|
||||
allows more graceful behavior on filesystems like sshfs.
|
||||
|
||||
* Stale temporary files under $GIT_DIR/objects/pack are now cleaned up
|
||||
automatically by "git prune".
|
||||
|
||||
* "Git.pm" tests relied on unnecessarily more recent version of Perl.
|
||||
|
||||
* "gitweb" triggered undef warning on commits without log messages.
|
||||
|
||||
Many other documentation updates.
|
||||
|
||||
--
|
||||
exec >/var/tmp/1
|
||||
O=v1.6.0.2-41-g7fe4a72
|
||||
echo O=$(git describe maint)
|
||||
git shortlog --no-merges $O..maint
|
|
@ -363,8 +363,17 @@ core.pager::
|
|||
variable. Note that git sets the `LESS` environment
|
||||
variable to `FRSX` if it is unset when it runs the
|
||||
pager. One can change these settings by setting the
|
||||
`LESS` variable to some other value or by giving the
|
||||
`core.pager` option a value such as "`less -+FRSX`".
|
||||
`LESS` variable to some other value. Alternately,
|
||||
these settings can be overridden on a project or
|
||||
global basis by setting the `core.pager` option.
|
||||
Setting `core.pager` has no affect on the `LESS`
|
||||
environment variable behaviour above, so if you want
|
||||
to override git's default settings this way, you need
|
||||
to be explicit. For example, to disable the S option
|
||||
in a backward compatible manner, set `core.pager`
|
||||
to "`less -+$LESS -FRX`". This will be passed to the
|
||||
shell by git, which will translate the final command to
|
||||
"`LESS=FRSX less -+FRSX -FRX`".
|
||||
|
||||
core.whitespace::
|
||||
A comma separated list of common whitespace problems to
|
||||
|
|
|
@ -160,7 +160,10 @@ Here are the "carry forward" rules:
|
|||
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
|
||||
3 nothing exists exists, use M if "initial checkout"
|
||||
H == M keep index otherwise
|
||||
exists fail
|
||||
H != M
|
||||
|
||||
clean I==H I==M
|
||||
------------------
|
||||
|
@ -207,6 +210,12 @@ you picked it up via e-mail in a patch form), `git diff-index
|
|||
merge, but it would not show in `git diff-index --cached $M`
|
||||
output after two-tree merge.
|
||||
|
||||
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 swiching 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
|
||||
of the path is kept as long as $H and $M are the same.
|
||||
|
||||
3-Way Merge
|
||||
~~~~~~~~~~~
|
||||
|
|
|
@ -60,7 +60,7 @@ OPTIONS
|
|||
linkgit:git-pack-objects[1].
|
||||
|
||||
-f::
|
||||
Pass the `--no-reuse-delta` option to 'git-pack-objects'. See
|
||||
Pass the `--no-reuse-object` option to `git-pack-objects`, see
|
||||
linkgit:git-pack-objects[1].
|
||||
|
||||
-q::
|
||||
|
|
|
@ -270,27 +270,27 @@ See linkgit:git[1] for details.
|
|||
Defining a custom hunk-header
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Each group of changes (called "hunk") in the textual diff output
|
||||
Each group of changes (called a "hunk") in the textual diff output
|
||||
is prefixed with a line of the form:
|
||||
|
||||
@@ -k,l +n,m @@ TEXT
|
||||
|
||||
The text is called 'hunk header', and by default a line that
|
||||
begins with an alphabet, an underscore or a dollar sign is used,
|
||||
which matches what GNU 'diff -p' output uses. This default
|
||||
selection however is not suited for some contents, and you can
|
||||
use customized pattern to make a selection.
|
||||
This is called a 'hunk header'. The "TEXT" portion is by default a line
|
||||
that begins with an alphabet, an underscore or a dollar sign; this
|
||||
matches what GNU 'diff -p' output uses. This default selection however
|
||||
is not suited for some contents, and you can use a customized pattern
|
||||
to make a selection.
|
||||
|
||||
First in .gitattributes, you would assign the `diff` attribute
|
||||
First, in .gitattributes, you would assign the `diff` attribute
|
||||
for paths.
|
||||
|
||||
------------------------
|
||||
*.tex diff=tex
|
||||
------------------------
|
||||
|
||||
Then, you would define "diff.tex.xfuncname" configuration to
|
||||
Then, you would define a "diff.tex.xfuncname" configuration to
|
||||
specify a regular expression that matches a line that you would
|
||||
want to appear as the hunk header, like this:
|
||||
want to appear as the hunk header "TEXT", like this:
|
||||
|
||||
------------------------
|
||||
[diff "tex"]
|
||||
|
|
|
@ -36,11 +36,25 @@ files:
|
|||
|
||||
- 'git-diff-tree' compares contents of two "tree" objects;
|
||||
|
||||
In all of these cases, the commands themselves compare
|
||||
corresponding paths in the two sets of files. The result of
|
||||
comparison is passed from these commands to what is internally
|
||||
called "diffcore", in a format similar to what is output when
|
||||
the -p option is not used. E.g.
|
||||
In all of these cases, the commands themselves first optionally limit
|
||||
the two sets of files by any pathspecs given on their command-lines,
|
||||
and compare corresponding paths in the two resulting sets of files.
|
||||
|
||||
The pathspecs are used to limit the world diff operates in. They remove
|
||||
the filepairs outside the specified sets of pathnames. E.g. If the
|
||||
input set of filepairs included:
|
||||
|
||||
------------------------------------------------
|
||||
:100644 100644 bcd1234... 0123456... M junkfile
|
||||
------------------------------------------------
|
||||
|
||||
but the command invocation was `git diff-files myfile`, then the
|
||||
junkfile entry would be removed from the list because only "myfile"
|
||||
is under consideration.
|
||||
|
||||
The result of comparison is passed from these commands to what is
|
||||
internally called "diffcore", in a format similar to what is output
|
||||
when the -p option is not used. E.g.
|
||||
|
||||
------------------------------------------------
|
||||
in-place edit :100644 100644 bcd1234... 0123456... M file0
|
||||
|
@ -52,9 +66,8 @@ unmerged :000000 000000 0000000... 0000000... U file6
|
|||
The diffcore mechanism is fed a list of such comparison results
|
||||
(each of which is called "filepair", although at this point each
|
||||
of them talks about a single file), and transforms such a list
|
||||
into another list. There are currently 6 such transformations:
|
||||
into another list. There are currently 5 such transformations:
|
||||
|
||||
- diffcore-pathspec
|
||||
- diffcore-break
|
||||
- diffcore-rename
|
||||
- diffcore-merge-broken
|
||||
|
@ -62,38 +75,14 @@ into another list. There are currently 6 such transformations:
|
|||
- diffcore-order
|
||||
|
||||
These are applied in sequence. The set of filepairs 'git-diff-{asterisk}'
|
||||
commands find are used as the input to diffcore-pathspec, and
|
||||
the output from diffcore-pathspec is used as the input to the
|
||||
commands find are used as the input to diffcore-break, and
|
||||
the output from diffcore-break is used as the input to the
|
||||
next transformation. The final result is then passed to the
|
||||
output routine and generates either diff-raw format (see Output
|
||||
format sections of the manual for 'git-diff-{asterisk}' commands) or
|
||||
diff-patch format.
|
||||
|
||||
|
||||
diffcore-pathspec: For Ignoring Files Outside Our Consideration
|
||||
---------------------------------------------------------------
|
||||
|
||||
The first transformation in the chain is diffcore-pathspec, and
|
||||
is controlled by giving the pathname parameters to the
|
||||
'git-diff-{asterisk}' commands on the command line. The pathspec is used
|
||||
to limit the world diff operates in. It removes the filepairs
|
||||
outside the specified set of pathnames. E.g. If the input set
|
||||
of filepairs included:
|
||||
|
||||
------------------------------------------------
|
||||
:100644 100644 bcd1234... 0123456... M junkfile
|
||||
------------------------------------------------
|
||||
|
||||
but the command invocation was `git diff-files myfile`, then the
|
||||
junkfile entry would be removed from the list because only "myfile"
|
||||
is under consideration.
|
||||
|
||||
Implementation note. For performance reasons, 'git-diff-tree'
|
||||
uses the pathname parameters on the command line to cull set of
|
||||
filepairs it feeds the diffcore mechanism itself, and does not
|
||||
use diffcore-pathspec, but the end result is the same.
|
||||
|
||||
|
||||
diffcore-break: For Splitting Up "Complete Rewrites"
|
||||
----------------------------------------------------
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "delta.h"
|
||||
#include "builtin.h"
|
||||
#include "string-list.h"
|
||||
#include "dir.h"
|
||||
|
||||
/*
|
||||
* --check turns on checking that the working tree matches the
|
||||
|
@ -2735,15 +2736,7 @@ static void remove_file(struct patch *patch, int rmdir_empty)
|
|||
warning("unable to remove submodule %s",
|
||||
patch->old_name);
|
||||
} else if (!unlink(patch->old_name) && rmdir_empty) {
|
||||
char *name = xstrdup(patch->old_name);
|
||||
char *end = strrchr(name, '/');
|
||||
while (end) {
|
||||
*end = 0;
|
||||
if (rmdir(name))
|
||||
break;
|
||||
end = strrchr(name, '/');
|
||||
}
|
||||
free(name);
|
||||
remove_path(patch->old_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,6 +111,8 @@ int cmd_archive(int argc, const char **argv, const char *prefix)
|
|||
{
|
||||
const char *remote = NULL;
|
||||
|
||||
git_config(git_default_config, NULL);
|
||||
|
||||
remote = extract_remote_arg(&argc, argv);
|
||||
if (remote)
|
||||
return run_remote_archiver(remote, argc, argv);
|
||||
|
|
|
@ -269,6 +269,8 @@ static int merge_working_tree(struct checkout_opts *opts,
|
|||
}
|
||||
|
||||
/* 2-way merge to the new branch */
|
||||
topts.initial_checkout = (!active_nr &&
|
||||
(old->commit == new->commit));
|
||||
topts.update = 1;
|
||||
topts.merge = 1;
|
||||
topts.gently = opts->merge;
|
||||
|
@ -326,7 +328,7 @@ static int merge_working_tree(struct checkout_opts *opts,
|
|||
commit_locked_index(lock_file))
|
||||
die("unable to write new index file");
|
||||
|
||||
if (!opts->force)
|
||||
if (!opts->force && !opts->quiet)
|
||||
show_local_changes(&new->commit->object);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -58,7 +58,7 @@ static struct option builtin_clone_options[] = {
|
|||
OPT_STRING(0, "reference", &option_reference, "repo",
|
||||
"reference repository"),
|
||||
OPT_STRING('o', "origin", &option_origin, "branch",
|
||||
"use <branch> instead or 'origin' to track upstream"),
|
||||
"use <branch> instead of 'origin' to track upstream"),
|
||||
OPT_STRING('u', "upload-pack", &option_upload_pack, "path",
|
||||
"path to git-upload-pack on the remote"),
|
||||
OPT_STRING(0, "depth", &option_depth, "depth",
|
||||
|
|
|
@ -639,7 +639,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
|
|||
active_cache_tree = cache_tree();
|
||||
if (cache_tree_update(active_cache_tree,
|
||||
active_cache, active_nr, 0, 0) < 0) {
|
||||
error("Error building trees");
|
||||
error("Error building trees; the index is unmerged?");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,12 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix)
|
|||
3 < rev.max_count)
|
||||
usage(diff_files_usage);
|
||||
|
||||
if (rev.max_count == -1 &&
|
||||
/*
|
||||
* "diff-files --base -p" should not combine merges because it
|
||||
* was not asked to. "diff-files -c -p" should not densify
|
||||
* (the user should ask with "diff-files --cc" explicitly).
|
||||
*/
|
||||
if (rev.max_count == -1 && !rev.combine_merges &&
|
||||
(rev.diffopt.output_format & DIFF_FORMAT_PATCH))
|
||||
rev.combine_merges = rev.dense_combined_merges = 1;
|
||||
|
||||
|
|
|
@ -223,7 +223,13 @@ static int builtin_diff_files(struct rev_info *revs, int argc, const char **argv
|
|||
argv++; argc--;
|
||||
}
|
||||
|
||||
if (revs->max_count == -1 &&
|
||||
/*
|
||||
* "diff --base" should not combine merges because it was not
|
||||
* asked to. "diff -c" should not densify (if the user wants
|
||||
* dense one, --cc can be explicitly asked for, or just rely
|
||||
* on the default).
|
||||
*/
|
||||
if (revs->max_count == -1 && !revs->combine_merges &&
|
||||
(revs->diffopt.output_format & DIFF_FORMAT_PATCH))
|
||||
revs->combine_merges = revs->dense_combined_merges = 1;
|
||||
|
||||
|
|
|
@ -320,9 +320,7 @@ static const char *find_wholine(const char *who, int wholen, const char *buf, un
|
|||
|
||||
static const char *copy_line(const char *buf)
|
||||
{
|
||||
const char *eol = strchr(buf, '\n');
|
||||
if (!eol)
|
||||
return "";
|
||||
const char *eol = strchrnul(buf, '\n');
|
||||
return xmemdupz(buf, eol - buf);
|
||||
}
|
||||
|
||||
|
|
|
@ -844,7 +844,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
|||
committer = git_committer_info(IDENT_ERROR_ON_NO_NAME);
|
||||
endpos = strchr(committer, '>');
|
||||
if (!endpos)
|
||||
die("bogos committer info %s\n", committer);
|
||||
die("bogus committer info %s\n", committer);
|
||||
add_signoff = xmemdupz(committer, endpos - committer + 1);
|
||||
}
|
||||
else if (!strcmp(argv[i], "--attach")) {
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "ll-merge.h"
|
||||
#include "interpolate.h"
|
||||
#include "attr.h"
|
||||
#include "dir.h"
|
||||
#include "merge-recursive.h"
|
||||
|
||||
static int subtree_merge;
|
||||
|
@ -416,24 +417,6 @@ static int update_stages(const char *path, struct diff_filespec *o,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int remove_path(const char *name)
|
||||
{
|
||||
int ret;
|
||||
char *slash, *dirs;
|
||||
|
||||
ret = unlink(name);
|
||||
if (ret)
|
||||
return ret;
|
||||
dirs = xstrdup(name);
|
||||
while ((slash = strrchr(name, '/'))) {
|
||||
*slash = '\0';
|
||||
if (rmdir(name) != 0)
|
||||
break;
|
||||
}
|
||||
free(dirs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int remove_file(int clean, const char *path, int no_wd)
|
||||
{
|
||||
int update_cache = index_only || clean;
|
||||
|
@ -444,10 +427,8 @@ static int remove_file(int clean, const char *path, int no_wd)
|
|||
return -1;
|
||||
}
|
||||
if (update_working_directory) {
|
||||
unlink(path);
|
||||
if (errno != ENOENT || errno != EISDIR)
|
||||
if (remove_path(path))
|
||||
return -1;
|
||||
remove_path(path);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -476,6 +476,8 @@ static int git_merge_config(const char *k, const char *v, void *cb)
|
|||
|
||||
buf = xstrdup(v);
|
||||
argc = split_cmdline(buf, &argv);
|
||||
if (argc < 0)
|
||||
die("Bad branch.%s.mergeoptions string", branch);
|
||||
argv = xrealloc(argv, sizeof(*argv) * (argc + 2));
|
||||
memmove(argv + 1, argv, sizeof(*argv) * (argc + 1));
|
||||
argc++;
|
||||
|
|
|
@ -465,7 +465,7 @@ static void write_pack_file(void)
|
|||
char tmpname[PATH_MAX];
|
||||
int fd;
|
||||
snprintf(tmpname, sizeof(tmpname),
|
||||
"%s/tmp_pack_XXXXXX", get_object_directory());
|
||||
"%s/pack/tmp_pack_XXXXXX", get_object_directory());
|
||||
fd = xmkstemp(tmpname);
|
||||
pack_tmp_name = xstrdup(tmpname);
|
||||
f = sha1fd(fd, pack_tmp_name);
|
||||
|
|
|
@ -13,7 +13,7 @@ static const char * const prune_usage[] = {
|
|||
static int show_only;
|
||||
static unsigned long expire;
|
||||
|
||||
static int prune_tmp_object(char *path, const char *filename)
|
||||
static int prune_tmp_object(const char *path, const char *filename)
|
||||
{
|
||||
const char *fullpath = mkpath("%s/%s", path, filename);
|
||||
if (expire) {
|
||||
|
@ -110,24 +110,22 @@ static void prune_object_dir(const char *path)
|
|||
/*
|
||||
* Write errors (particularly out of space) can result in
|
||||
* failed temporary packs (and more rarely indexes and other
|
||||
* files begining with "tmp_") accumulating in the
|
||||
* object directory.
|
||||
* files begining with "tmp_") accumulating in the object
|
||||
* and the pack directories.
|
||||
*/
|
||||
static void remove_temporary_files(void)
|
||||
static void remove_temporary_files(const char *path)
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *de;
|
||||
char* dirname=get_object_directory();
|
||||
|
||||
dir = opendir(dirname);
|
||||
dir = opendir(path);
|
||||
if (!dir) {
|
||||
fprintf(stderr, "Unable to open object directory %s\n",
|
||||
dirname);
|
||||
fprintf(stderr, "Unable to open directory %s\n", path);
|
||||
return;
|
||||
}
|
||||
while ((de = readdir(dir)) != NULL)
|
||||
if (!prefixcmp(de->d_name, "tmp_"))
|
||||
prune_tmp_object(dirname, de->d_name);
|
||||
prune_tmp_object(path, de->d_name);
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
|
@ -141,6 +139,7 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
|
|||
"expire objects older than <time>"),
|
||||
OPT_END()
|
||||
};
|
||||
char *s;
|
||||
|
||||
save_commit_buffer = 0;
|
||||
init_revisions(&revs, prefix);
|
||||
|
@ -163,6 +162,9 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
|
|||
prune_object_dir(get_object_directory());
|
||||
|
||||
prune_packed_objects(show_only);
|
||||
remove_temporary_files();
|
||||
remove_temporary_files(get_object_directory());
|
||||
s = xstrdup(mkpath("%s/pack", get_object_directory()));
|
||||
remove_temporary_files(s);
|
||||
free(s);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -206,6 +206,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
|
|||
break;
|
||||
case 2:
|
||||
opts.fn = twoway_merge;
|
||||
opts.initial_checkout = !active_nr;
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
|
|
|
@ -407,14 +407,15 @@ static int rm(int argc, const char **argv)
|
|||
return i;
|
||||
}
|
||||
|
||||
static void show_list(const char *title, struct string_list *list)
|
||||
static void show_list(const char *title, struct string_list *list,
|
||||
const char *extra_arg)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!list->nr)
|
||||
return;
|
||||
|
||||
printf(title, list->nr > 1 ? "es" : "");
|
||||
printf(title, list->nr > 1 ? "es" : "", extra_arg);
|
||||
printf("\n ");
|
||||
for (i = 0; i < list->nr; i++)
|
||||
printf("%s%s", i ? " " : "", list->items[i].string);
|
||||
|
@ -477,7 +478,6 @@ static int show(int argc, const char **argv)
|
|||
|
||||
memset(&states, 0, sizeof(states));
|
||||
for (; argc; argc--, argv++) {
|
||||
struct strbuf buf;
|
||||
int i;
|
||||
|
||||
get_remote_ref_states(*argv, &states, !no_query);
|
||||
|
@ -503,18 +503,16 @@ static int show(int argc, const char **argv)
|
|||
}
|
||||
|
||||
if (!no_query) {
|
||||
strbuf_init(&buf, 0);
|
||||
strbuf_addf(&buf, " New remote branch%%s (next fetch "
|
||||
"will store in remotes/%s)", states.remote->name);
|
||||
show_list(buf.buf, &states.new);
|
||||
strbuf_release(&buf);
|
||||
show_list(" New remote branch%s (next fetch "
|
||||
"will store in remotes/%s)",
|
||||
&states.new, states.remote->name);
|
||||
show_list(" Stale tracking branch%s (use 'git remote "
|
||||
"prune')", &states.stale);
|
||||
"prune')", &states.stale, "");
|
||||
}
|
||||
|
||||
if (no_query)
|
||||
for_each_ref(append_ref_to_tracked_list, &states);
|
||||
show_list(" Tracked remote branch%s", &states.tracked);
|
||||
show_list(" Tracked remote branch%s", &states.tracked, "");
|
||||
|
||||
if (states.remote->push_refspec_nr) {
|
||||
printf(" Local branch%s pushed with 'git push'\n ",
|
||||
|
@ -652,10 +650,13 @@ static int get_one_entry(struct remote *remote, void *priv)
|
|||
{
|
||||
struct string_list *list = priv;
|
||||
|
||||
string_list_append(remote->name, list)->util = remote->url_nr ?
|
||||
(void *)remote->url[0] : NULL;
|
||||
if (remote->url_nr > 1)
|
||||
warning("Remote %s has more than one URL", remote->name);
|
||||
if (remote->url_nr > 0) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < remote->url_nr; i++)
|
||||
string_list_append(remote->name, list)->util = (void *)remote->url[i];
|
||||
} else
|
||||
string_list_append(remote->name, list)->util = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -671,10 +672,14 @@ static int show_all(void)
|
|||
sort_string_list(&list);
|
||||
for (i = 0; i < list.nr; i++) {
|
||||
struct string_list_item *item = list.items + i;
|
||||
printf("%s%s%s\n", item->string,
|
||||
verbose ? "\t" : "",
|
||||
verbose && item->util ?
|
||||
(const char *)item->util : "");
|
||||
if (verbose)
|
||||
printf("%s\t%s\n", item->string,
|
||||
item->util ? (const char *)item->util : "");
|
||||
else {
|
||||
if (i && !strcmp((item - 1)->string, item->string))
|
||||
continue;
|
||||
printf("%s\n", item->string);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
|
22
builtin-rm.c
22
builtin-rm.c
|
@ -29,26 +29,6 @@ static void add_list(const char *name)
|
|||
list.name[list.nr++] = name;
|
||||
}
|
||||
|
||||
static int remove_file(const char *name)
|
||||
{
|
||||
int ret;
|
||||
char *slash;
|
||||
|
||||
ret = unlink(name);
|
||||
if (ret && errno == ENOENT)
|
||||
/* The user has removed it from the filesystem by hand */
|
||||
ret = errno = 0;
|
||||
|
||||
if (!ret && (slash = strrchr(name, '/'))) {
|
||||
char *n = xstrdup(name);
|
||||
do {
|
||||
n[slash - name] = 0;
|
||||
name = n;
|
||||
} while (!rmdir(name) && (slash = strrchr(name, '/')));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int check_local_mod(unsigned char *head, int index_only)
|
||||
{
|
||||
/* items in list are already sorted in the cache order,
|
||||
|
@ -239,7 +219,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
|
|||
int removed = 0;
|
||||
for (i = 0; i < list.nr; i++) {
|
||||
const char *path = list.name[i];
|
||||
if (!remove_file(path)) {
|
||||
if (!remove_path(path)) {
|
||||
removed = 1;
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -750,7 +750,7 @@ _git_commit ()
|
|||
--*)
|
||||
__gitcomp "
|
||||
--all --author= --signoff --verify --no-verify
|
||||
--edit --amend --include --only
|
||||
--edit --amend --include --only --interactive
|
||||
"
|
||||
return
|
||||
esac
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
)) { die $usage; }
|
||||
die $usage unless ($read_mode xor $write_mode);
|
||||
|
||||
my $topdir = `git-rev-parse --show-cdup` or die "\n"; chomp $topdir;
|
||||
my $topdir = `git rev-parse --show-cdup` or die "\n"; chomp $topdir;
|
||||
my $gitdir = $topdir . '.git';
|
||||
my $gitmeta = $topdir . '.gitmeta';
|
||||
|
||||
|
@ -155,7 +155,7 @@
|
|||
open (OUT, ">$gitmeta.tmp") or die "Could not open $gitmeta.tmp for writing: $!\n";
|
||||
}
|
||||
|
||||
my @files = `git-ls-files`;
|
||||
my @files = `git ls-files`;
|
||||
my %dirs;
|
||||
|
||||
foreach my $path (@files) {
|
||||
|
|
12
diff.c
12
diff.c
|
@ -2417,13 +2417,6 @@ int diff_setup_done(struct diff_options *options)
|
|||
DIFF_OPT_SET(options, EXIT_WITH_STATUS);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we postprocess in diffcore, we cannot simply return
|
||||
* upon the first hit. We need to run diff as usual.
|
||||
*/
|
||||
if (options->pickaxe || options->filter)
|
||||
DIFF_OPT_CLR(options, QUIET);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3411,10 +3404,7 @@ static void diffcore_skip_stat_unmatch(struct diff_options *diffopt)
|
|||
|
||||
void diffcore_std(struct diff_options *options)
|
||||
{
|
||||
if (DIFF_OPT_TST(options, QUIET))
|
||||
return;
|
||||
|
||||
if (options->skip_stat_unmatch && !DIFF_OPT_TST(options, FIND_COPIES_HARDER))
|
||||
if (options->skip_stat_unmatch)
|
||||
diffcore_skip_stat_unmatch(options);
|
||||
if (options->break_opt != -1)
|
||||
diffcore_break(options->break_opt);
|
||||
|
|
|
@ -92,7 +92,6 @@ extern struct diff_filepair *diff_queue(struct diff_queue_struct *,
|
|||
struct diff_filespec *);
|
||||
extern void diff_q(struct diff_queue_struct *, struct diff_filepair *);
|
||||
|
||||
extern void diffcore_pathspec(const char **pathspec);
|
||||
extern void diffcore_break(int);
|
||||
extern void diffcore_rename(struct diff_options *);
|
||||
extern void diffcore_merge_broken(void);
|
||||
|
|
20
dir.c
20
dir.c
|
@ -831,3 +831,23 @@ void setup_standard_excludes(struct dir_struct *dir)
|
|||
if (excludes_file && !access(excludes_file, R_OK))
|
||||
add_excludes_from_file(dir, excludes_file);
|
||||
}
|
||||
|
||||
int remove_path(const char *name)
|
||||
{
|
||||
char *slash;
|
||||
|
||||
if (unlink(name) && errno != ENOENT)
|
||||
return -1;
|
||||
|
||||
slash = strrchr(name, '/');
|
||||
if (slash) {
|
||||
char *dirs = xstrdup(name);
|
||||
slash = dirs + (slash - name);
|
||||
do {
|
||||
*slash = '\0';
|
||||
} while (rmdir(dirs) && (slash = strrchr(dirs, '/')));
|
||||
free(dirs);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
3
dir.h
3
dir.h
|
@ -81,4 +81,7 @@ extern int is_inside_dir(const char *dir);
|
|||
extern void setup_standard_excludes(struct dir_struct *dir);
|
||||
extern int remove_dir_recursively(struct strbuf *path, int only_empty);
|
||||
|
||||
/* tries to remove the path with empty directories along it, ignores ENOENT */
|
||||
extern int remove_path(const char *path);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -816,7 +816,7 @@ static void start_packfile(void)
|
|||
int pack_fd;
|
||||
|
||||
snprintf(tmpfile, sizeof(tmpfile),
|
||||
"%s/tmp_pack_XXXXXX", get_object_directory());
|
||||
"%s/pack/tmp_pack_XXXXXX", get_object_directory());
|
||||
pack_fd = xmkstemp(tmpfile);
|
||||
p = xcalloc(1, sizeof(*p) + strlen(tmpfile) + 2);
|
||||
strcpy(p->pack_name, tmpfile);
|
||||
|
@ -878,7 +878,7 @@ static char *create_index(void)
|
|||
}
|
||||
|
||||
snprintf(tmpfile, sizeof(tmpfile),
|
||||
"%s/tmp_idx_XXXXXX", get_object_directory());
|
||||
"%s/pack/tmp_idx_XXXXXX", get_object_directory());
|
||||
idx_fd = xmkstemp(tmpfile);
|
||||
f = sha1fd(idx_fd, tmpfile);
|
||||
sha1write(f, array, 256 * sizeof(int));
|
||||
|
|
|
@ -284,7 +284,7 @@ do_next () {
|
|||
pick_one $sha1 ||
|
||||
die_with_patch $sha1 "Could not apply $sha1... $rest"
|
||||
make_patch $sha1
|
||||
: > "$DOTEST"/amend
|
||||
git rev-parse --verify HEAD > "$DOTEST"/amend
|
||||
warn "Stopped at $sha1... $rest"
|
||||
warn "You can amend the commit now, with"
|
||||
warn
|
||||
|
@ -427,14 +427,22 @@ do
|
|||
else
|
||||
. "$DOTEST"/author-script ||
|
||||
die "Cannot find the author identity"
|
||||
amend=
|
||||
if test -f "$DOTEST"/amend
|
||||
then
|
||||
amend=$(git rev-parse --verify HEAD)
|
||||
test "$amend" = $(cat "$DOTEST"/amend) ||
|
||||
die "\
|
||||
You have uncommitted changes in your working tree. Please, commit them
|
||||
first and then run 'git rebase --continue' again."
|
||||
git reset --soft HEAD^ ||
|
||||
die "Cannot rewind the HEAD"
|
||||
fi
|
||||
export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE &&
|
||||
git commit --no-verify -F "$DOTEST"/message -e ||
|
||||
git commit --no-verify -F "$DOTEST"/message -e || {
|
||||
test -n "$amend" && git reset --soft $amend
|
||||
die "Could not commit staged changes."
|
||||
}
|
||||
fi
|
||||
|
||||
require_clean_work_tree
|
||||
|
|
|
@ -10,7 +10,7 @@ git repack [options]
|
|||
a pack everything in a single pack
|
||||
A same as -a, and turn unreachable objects loose
|
||||
d remove redundant packs, and run git-prune-packed
|
||||
f pass --no-reuse-delta to git-pack-objects
|
||||
f pass --no-reuse-object to git-pack-objects
|
||||
n do not run git-update-server-info
|
||||
q,quiet be quiet
|
||||
l pass --local to git-pack-objects
|
||||
|
|
19
git-stash.sh
19
git-stash.sh
|
@ -144,7 +144,14 @@ show_stash () {
|
|||
then
|
||||
flags=--stat
|
||||
fi
|
||||
s=$(git rev-parse --revs-only --no-flags --default $ref_stash "$@")
|
||||
|
||||
if test $# = 0
|
||||
then
|
||||
set x "$ref_stash@{0}"
|
||||
shift
|
||||
fi
|
||||
|
||||
s=$(git rev-parse --revs-only --no-flags "$@")
|
||||
|
||||
w_commit=$(git rev-parse --verify "$s") &&
|
||||
b_commit=$(git rev-parse --verify "$s^") &&
|
||||
|
@ -154,7 +161,7 @@ show_stash () {
|
|||
apply_stash () {
|
||||
git update-index -q --refresh &&
|
||||
git diff-files --quiet --ignore-submodules ||
|
||||
die 'Cannot restore on top of a dirty state'
|
||||
die 'Cannot apply to a dirty working tree, please stage your changes'
|
||||
|
||||
unstash_index=
|
||||
case "$1" in
|
||||
|
@ -163,13 +170,19 @@ apply_stash () {
|
|||
shift
|
||||
esac
|
||||
|
||||
if test $# = 0
|
||||
then
|
||||
set x "$ref_stash@{0}"
|
||||
shift
|
||||
fi
|
||||
|
||||
# current index state
|
||||
c_tree=$(git write-tree) ||
|
||||
die 'Cannot apply a stash in the middle of a merge'
|
||||
|
||||
# stash records the work tree, and is a merge between the
|
||||
# base commit (first parent) and the index tree (second parent).
|
||||
s=$(git rev-parse --revs-only --no-flags --default $ref_stash "$@") &&
|
||||
s=$(git rev-parse --revs-only --no-flags "$@") &&
|
||||
w_tree=$(git rev-parse --verify "$s:") &&
|
||||
b_tree=$(git rev-parse --verify "$s^1:") &&
|
||||
i_tree=$(git rev-parse --verify "$s^2:") ||
|
||||
|
|
|
@ -194,7 +194,7 @@ cmd_add()
|
|||
else
|
||||
|
||||
module_clone "$path" "$realrepo" || exit
|
||||
(unset GIT_DIR; cd "$path" && git checkout -q ${branch:+-b "$branch" "origin/$branch"}) ||
|
||||
(unset GIT_DIR; cd "$path" && git checkout -f -q ${branch:+-b "$branch" "origin/$branch"}) ||
|
||||
die "Unable to checkout submodule '$path'"
|
||||
fi
|
||||
|
||||
|
@ -340,8 +340,13 @@ cmd_update()
|
|||
|
||||
if test "$subsha1" != "$sha1"
|
||||
then
|
||||
force=
|
||||
if test -z "$subsha1"
|
||||
then
|
||||
force="-f"
|
||||
fi
|
||||
(unset GIT_DIR; cd "$path" && git-fetch &&
|
||||
git-checkout -q "$sha1") ||
|
||||
git-checkout $force -q "$sha1") ||
|
||||
die "Unable to checkout '$sha1' in submodule path '$path'"
|
||||
|
||||
say "Submodule path '$path': checked out '$sha1'"
|
||||
|
|
16
git-svn.perl
16
git-svn.perl
|
@ -4010,21 +4010,21 @@ sub gs_do_switch {
|
|||
my $old_url = $full_url;
|
||||
$full_url .= '/' . escape_uri_only($path) if length $path;
|
||||
my ($ra, $reparented);
|
||||
if ($old_url ne $full_url) {
|
||||
if ($old_url !~ m#^svn(\+ssh)?://#) {
|
||||
SVN::_Ra::svn_ra_reparent($self->{session}, $full_url,
|
||||
$pool);
|
||||
$self->{url} = $full_url;
|
||||
$reparented = 1;
|
||||
} else {
|
||||
|
||||
if ($old_url =~ m#^svn(\+ssh)?://#) {
|
||||
$_[0] = undef;
|
||||
$self = undef;
|
||||
$RA = undef;
|
||||
$ra = Git::SVN::Ra->new($full_url);
|
||||
$ra_invalid = 1;
|
||||
} elsif ($old_url ne $full_url) {
|
||||
SVN::_Ra::svn_ra_reparent($self->{session}, $full_url, $pool);
|
||||
$self->{url} = $full_url;
|
||||
$reparented = 1;
|
||||
}
|
||||
}
|
||||
|
||||
$ra ||= $self;
|
||||
$url_b = escape_url($url_b);
|
||||
my $reporter = $ra->do_switch($rev_b, '', 1, $url_b, $editor, $pool);
|
||||
my @lock = $SVN::Core::VERSION ge '1.2.0' ? (undef) : ();
|
||||
$reporter->set_path('', $rev_a, 0, @lock, $pool);
|
||||
|
|
2
git.c
2
git.c
|
@ -162,6 +162,8 @@ static int handle_alias(int *argcp, const char ***argv)
|
|||
alias_string + 1, alias_command);
|
||||
}
|
||||
count = split_cmdline(alias_string, &new_argv);
|
||||
if (count < 0)
|
||||
die("Bad alias.%s string", alias_command);
|
||||
option_count = handle_options(&new_argv, &count, &envchanged);
|
||||
if (envchanged)
|
||||
die("alias '%s' changes environment variables\n"
|
||||
|
|
|
@ -2123,7 +2123,7 @@ sub parse_commit_text {
|
|||
last;
|
||||
}
|
||||
}
|
||||
if ($co{'title'} eq "") {
|
||||
if (! defined $co{'title'} || $co{'title'} eq "") {
|
||||
$co{'title'} = $co{'title_short'} = '(no commit message)';
|
||||
}
|
||||
# remove added spaces
|
||||
|
|
11
http.c
11
http.c
|
@ -165,7 +165,16 @@ static CURL* get_curl_handle(void)
|
|||
{
|
||||
CURL* result = curl_easy_init();
|
||||
|
||||
curl_easy_setopt(result, CURLOPT_SSL_VERIFYPEER, curl_ssl_verify);
|
||||
if (!curl_ssl_verify) {
|
||||
curl_easy_setopt(result, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
curl_easy_setopt(result, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
} else {
|
||||
/* Verify authenticity of the peer's certificate */
|
||||
curl_easy_setopt(result, CURLOPT_SSL_VERIFYPEER, 1);
|
||||
/* The name in the cert must match whom we tried to connect */
|
||||
curl_easy_setopt(result, CURLOPT_SSL_VERIFYHOST, 2);
|
||||
}
|
||||
|
||||
#if LIBCURL_VERSION_NUM >= 0x070907
|
||||
curl_easy_setopt(result, CURLOPT_NETRC, CURL_NETRC_OPTIONAL);
|
||||
#endif
|
||||
|
|
|
@ -172,7 +172,7 @@ static char *open_pack_file(char *pack_name)
|
|||
if (!pack_name) {
|
||||
static char tmpfile[PATH_MAX];
|
||||
snprintf(tmpfile, sizeof(tmpfile),
|
||||
"%s/tmp_pack_XXXXXX", get_object_directory());
|
||||
"%s/pack/tmp_pack_XXXXXX", get_object_directory());
|
||||
output_fd = xmkstemp(tmpfile);
|
||||
pack_name = xstrdup(tmpfile);
|
||||
} else
|
||||
|
|
|
@ -45,7 +45,7 @@ char *write_idx_file(char *index_name, struct pack_idx_entry **objects,
|
|||
if (!index_name) {
|
||||
static char tmpfile[PATH_MAX];
|
||||
snprintf(tmpfile, sizeof(tmpfile),
|
||||
"%s/tmp_idx_XXXXXX", get_object_directory());
|
||||
"%s/pack/tmp_idx_XXXXXX", get_object_directory());
|
||||
fd = xmkstemp(tmpfile);
|
||||
index_name = xstrdup(tmpfile);
|
||||
} else {
|
||||
|
|
|
@ -1253,6 +1253,7 @@ int discard_index(struct index_state *istate)
|
|||
istate->cache_nr = 0;
|
||||
istate->cache_changed = 0;
|
||||
istate->timestamp = 0;
|
||||
istate->name_hash_initialized = 0;
|
||||
free_hash(&istate->name_hash);
|
||||
cache_tree_free(&(istate->cache_tree));
|
||||
free(istate->alloc);
|
||||
|
|
|
@ -2136,7 +2136,9 @@ static void write_sha1_file_prepare(const void *buf, unsigned long len,
|
|||
*/
|
||||
int move_temp_to_file(const char *tmpfile, const char *filename)
|
||||
{
|
||||
int ret = link(tmpfile, filename);
|
||||
int ret = 0;
|
||||
if (link(tmpfile, filename))
|
||||
ret = errno;
|
||||
|
||||
/*
|
||||
* Coda hack - coda doesn't like cross-directory links,
|
||||
|
|
|
@ -135,3 +135,20 @@ close $wr or die $!;
|
|||
close $rd or die $!;
|
||||
EOF
|
||||
}
|
||||
|
||||
require_svnserve () {
|
||||
if test -z "$SVNSERVE_PORT"
|
||||
then
|
||||
say 'skipping svnserve test. (set $SVNSERVE_PORT to enable)'
|
||||
test_done
|
||||
exit
|
||||
fi
|
||||
}
|
||||
|
||||
start_svnserve () {
|
||||
svnserve --listen-port $SVNSERVE_PORT \
|
||||
--root "$rawsvnrepo" \
|
||||
--listen-once \
|
||||
--listen-host 127.0.0.1 &
|
||||
}
|
||||
|
||||
|
|
46
t/t0024-crlf-archive.sh
Normal file
46
t/t0024-crlf-archive.sh
Normal file
|
@ -0,0 +1,46 @@
|
|||
#!/bin/sh
|
||||
|
||||
test_description='respect crlf in git archive'
|
||||
|
||||
. ./test-lib.sh
|
||||
UNZIP=${UNZIP:-unzip}
|
||||
|
||||
test_expect_success setup '
|
||||
|
||||
git config core.autocrlf true
|
||||
|
||||
printf "CRLF line ending\r\nAnd another\r\n" > sample &&
|
||||
git add sample &&
|
||||
|
||||
test_tick &&
|
||||
git commit -m Initial
|
||||
|
||||
'
|
||||
|
||||
test_expect_success 'tar archive' '
|
||||
|
||||
git archive --format=tar HEAD |
|
||||
( mkdir untarred && cd untarred && "$TAR" -xf - )
|
||||
|
||||
test_cmp sample untarred/sample
|
||||
|
||||
'
|
||||
|
||||
"$UNZIP" -v >/dev/null 2>&1
|
||||
if [ $? -eq 127 ]; then
|
||||
echo "Skipping ZIP test, because unzip was not found"
|
||||
test_done
|
||||
exit
|
||||
fi
|
||||
|
||||
test_expect_success 'zip archive' '
|
||||
|
||||
git archive --format=zip HEAD >test.zip &&
|
||||
|
||||
( mkdir unzipped && cd unzipped && unzip ../test.zip ) &&
|
||||
|
||||
test_cmp sample unzipped/sample
|
||||
|
||||
'
|
||||
|
||||
test_done
|
|
@ -741,4 +741,14 @@ test_expect_success 'symlinked configuration' '
|
|||
|
||||
'
|
||||
|
||||
test_expect_success 'check split_cmdline return' "
|
||||
git config alias.split-cmdline-fix 'echo \"' &&
|
||||
test_must_fail git split-cmdline-fix &&
|
||||
echo foo > foo &&
|
||||
git add foo &&
|
||||
git commit -m 'initial commit' &&
|
||||
git config branch.master.mergeoptions 'echo \"' &&
|
||||
test_must_fail git merge master
|
||||
"
|
||||
|
||||
test_done
|
||||
|
|
|
@ -535,4 +535,15 @@ test_expect_success 'reset and bind merge' '
|
|||
|
||||
'
|
||||
|
||||
test_expect_success 'merge removes empty directories' '
|
||||
|
||||
git reset --hard master &&
|
||||
git checkout -b rm &&
|
||||
git rm d/e &&
|
||||
git commit -mremoved-d/e &&
|
||||
git checkout master &&
|
||||
git merge -s recursive rm &&
|
||||
test_must_fail test -d d
|
||||
'
|
||||
|
||||
test_done
|
||||
|
|
|
@ -12,19 +12,7 @@ test_description='git-svn dcommit new files over svn:// test'
|
|||
|
||||
. ./lib-git-svn.sh
|
||||
|
||||
if test -z "$SVNSERVE_PORT"
|
||||
then
|
||||
say 'skipping svnserve test. (set $SVNSERVE_PORT to enable)'
|
||||
test_done
|
||||
exit
|
||||
fi
|
||||
|
||||
start_svnserve () {
|
||||
svnserve --listen-port $SVNSERVE_PORT \
|
||||
--root "$rawsvnrepo" \
|
||||
--listen-once \
|
||||
--listen-host 127.0.0.1 &
|
||||
}
|
||||
require_svnserve
|
||||
|
||||
test_expect_success 'start tracking an empty repo' '
|
||||
svn mkdir -m "empty dir" "$svnrepo"/empty-dir &&
|
||||
|
|
|
@ -6,6 +6,10 @@
|
|||
test_description='git-svn funky branch names'
|
||||
. ./lib-git-svn.sh
|
||||
|
||||
# Abo-Uebernahme (Bug #994)
|
||||
scary_uri='Abo-Uebernahme%20%28Bug%20%23994%29'
|
||||
scary_ref='Abo-Uebernahme%20(Bug%20#994)'
|
||||
|
||||
test_expect_success 'setup svnrepo' '
|
||||
mkdir project project/trunk project/branches project/tags &&
|
||||
echo foo > project/trunk/foo &&
|
||||
|
@ -15,6 +19,8 @@ test_expect_success 'setup svnrepo' '
|
|||
"$svnrepo/pr ject/branches/fun plugin" &&
|
||||
svn cp -m "more fun!" "$svnrepo/pr ject/branches/fun plugin" \
|
||||
"$svnrepo/pr ject/branches/more fun plugin!" &&
|
||||
svn cp -m "scary" "$svnrepo/pr ject/branches/fun plugin" \
|
||||
"$svnrepo/pr ject/branches/$scary_uri" &&
|
||||
start_httpd
|
||||
'
|
||||
|
||||
|
@ -23,6 +29,7 @@ test_expect_success 'test clone with funky branch names' '
|
|||
cd project &&
|
||||
git rev-parse "refs/remotes/fun%20plugin" &&
|
||||
git rev-parse "refs/remotes/more%20fun%20plugin!" &&
|
||||
git rev-parse "refs/remotes/$scary_ref" &&
|
||||
cd ..
|
||||
'
|
||||
|
||||
|
@ -35,6 +42,15 @@ test_expect_success 'test dcommit to funky branch' "
|
|||
cd ..
|
||||
"
|
||||
|
||||
test_expect_success 'test dcommit to scary branch' '
|
||||
cd project &&
|
||||
git reset --hard "refs/remotes/$scary_ref" &&
|
||||
echo urls are scary >> foo &&
|
||||
git commit -m "eep" -- foo &&
|
||||
git svn dcommit &&
|
||||
cd ..
|
||||
'
|
||||
|
||||
stop_httpd
|
||||
|
||||
test_done
|
||||
|
|
22
t/t9126-git-svn-follow-deleted-readded-directory.sh
Executable file
22
t/t9126-git-svn-follow-deleted-readded-directory.sh
Executable file
|
@ -0,0 +1,22 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2008 Alec Berryman
|
||||
|
||||
test_description='git svn fetch repository with deleted and readded directory'
|
||||
|
||||
. ./lib-git-svn.sh
|
||||
|
||||
# Don't run this by default; it opens up a port.
|
||||
require_svnserve
|
||||
|
||||
test_expect_success 'load repository' '
|
||||
svnadmin load -q "$rawsvnrepo" < "$TEST_DIRECTORY"/t9126/follow-deleted-readded.dump
|
||||
'
|
||||
|
||||
test_expect_success 'fetch repository' '
|
||||
start_svnserve &&
|
||||
git svn init svn://127.0.0.1:$SVNSERVE_PORT &&
|
||||
git svn fetch
|
||||
'
|
||||
|
||||
test_done
|
201
t/t9126/follow-deleted-readded.dump
Normal file
201
t/t9126/follow-deleted-readded.dump
Normal file
|
@ -0,0 +1,201 @@
|
|||
SVN-fs-dump-format-version: 2
|
||||
|
||||
UUID: 1807dc6f-c693-4cda-9710-00e1be8c1f21
|
||||
|
||||
Revision-number: 0
|
||||
Prop-content-length: 56
|
||||
Content-length: 56
|
||||
|
||||
K 8
|
||||
svn:date
|
||||
V 27
|
||||
2008-09-14T19:53:13.006748Z
|
||||
PROPS-END
|
||||
|
||||
Revision-number: 1
|
||||
Prop-content-length: 111
|
||||
Content-length: 111
|
||||
|
||||
K 7
|
||||
svn:log
|
||||
V 12
|
||||
Create trunk
|
||||
K 10
|
||||
svn:author
|
||||
V 4
|
||||
alec
|
||||
K 8
|
||||
svn:date
|
||||
V 27
|
||||
2008-09-14T19:53:13.239689Z
|
||||
PROPS-END
|
||||
|
||||
Node-path: trunk
|
||||
Node-kind: dir
|
||||
Node-action: add
|
||||
Prop-content-length: 10
|
||||
Content-length: 10
|
||||
|
||||
PROPS-END
|
||||
|
||||
|
||||
Revision-number: 2
|
||||
Prop-content-length: 119
|
||||
Content-length: 119
|
||||
|
||||
K 7
|
||||
svn:log
|
||||
V 20
|
||||
Create trunk/project
|
||||
K 10
|
||||
svn:author
|
||||
V 4
|
||||
alec
|
||||
K 8
|
||||
svn:date
|
||||
V 27
|
||||
2008-09-14T19:53:13.548860Z
|
||||
PROPS-END
|
||||
|
||||
Node-path: trunk/project
|
||||
Node-kind: dir
|
||||
Node-action: add
|
||||
Prop-content-length: 10
|
||||
Content-length: 10
|
||||
|
||||
PROPS-END
|
||||
|
||||
|
||||
Revision-number: 3
|
||||
Prop-content-length: 111
|
||||
Content-length: 111
|
||||
|
||||
K 7
|
||||
svn:log
|
||||
V 12
|
||||
add new file
|
||||
K 10
|
||||
svn:author
|
||||
V 4
|
||||
alec
|
||||
K 8
|
||||
svn:date
|
||||
V 27
|
||||
2008-09-14T19:53:15.433630Z
|
||||
PROPS-END
|
||||
|
||||
Node-path: trunk/project/foo
|
||||
Node-kind: file
|
||||
Node-action: add
|
||||
Prop-content-length: 10
|
||||
Text-content-length: 4
|
||||
Text-content-md5: d3b07384d113edec49eaa6238ad5ff00
|
||||
Content-length: 14
|
||||
|
||||
PROPS-END
|
||||
foo
|
||||
|
||||
|
||||
Revision-number: 4
|
||||
Prop-content-length: 116
|
||||
Content-length: 116
|
||||
|
||||
K 7
|
||||
svn:log
|
||||
V 17
|
||||
change foo to bar
|
||||
K 10
|
||||
svn:author
|
||||
V 4
|
||||
alec
|
||||
K 8
|
||||
svn:date
|
||||
V 27
|
||||
2008-09-14T19:53:17.339884Z
|
||||
PROPS-END
|
||||
|
||||
Node-path: trunk/project/foo
|
||||
Node-kind: file
|
||||
Node-action: change
|
||||
Text-content-length: 4
|
||||
Text-content-md5: c157a79031e1c40f85931829bc5fc552
|
||||
Content-length: 4
|
||||
|
||||
bar
|
||||
|
||||
|
||||
Revision-number: 5
|
||||
Prop-content-length: 114
|
||||
Content-length: 114
|
||||
|
||||
K 7
|
||||
svn:log
|
||||
V 15
|
||||
don't like that
|
||||
K 10
|
||||
svn:author
|
||||
V 4
|
||||
alec
|
||||
K 8
|
||||
svn:date
|
||||
V 27
|
||||
2008-09-14T19:53:19.335001Z
|
||||
PROPS-END
|
||||
|
||||
Node-path: trunk/project
|
||||
Node-action: delete
|
||||
|
||||
|
||||
Revision-number: 6
|
||||
Prop-content-length: 110
|
||||
Content-length: 110
|
||||
|
||||
K 7
|
||||
svn:log
|
||||
V 11
|
||||
reset trunk
|
||||
K 10
|
||||
svn:author
|
||||
V 4
|
||||
alec
|
||||
K 8
|
||||
svn:date
|
||||
V 27
|
||||
2008-09-14T19:53:19.845897Z
|
||||
PROPS-END
|
||||
|
||||
Node-path: trunk/project
|
||||
Node-kind: dir
|
||||
Node-action: add
|
||||
Node-copyfrom-rev: 4
|
||||
Node-copyfrom-path: trunk/project
|
||||
|
||||
|
||||
Revision-number: 7
|
||||
Prop-content-length: 113
|
||||
Content-length: 113
|
||||
|
||||
K 7
|
||||
svn:log
|
||||
V 14
|
||||
change to quux
|
||||
K 10
|
||||
svn:author
|
||||
V 4
|
||||
alec
|
||||
K 8
|
||||
svn:date
|
||||
V 27
|
||||
2008-09-14T19:53:21.367947Z
|
||||
PROPS-END
|
||||
|
||||
Node-path: trunk/project/foo
|
||||
Node-kind: file
|
||||
Node-action: change
|
||||
Text-content-length: 5
|
||||
Text-content-md5: d3b07a382ec010c01889250fce66fb13
|
||||
Content-length: 5
|
||||
|
||||
quux
|
||||
|
||||
|
|
@ -31,9 +31,11 @@ boilerplates.made : $(bpsrc)
|
|||
dir=`expr "$$dst" : '\(.*\)/'` && \
|
||||
mkdir -p blt/$$dir && \
|
||||
case "$$boilerplate" in \
|
||||
*--) ;; \
|
||||
*) cp -p $$boilerplate blt/$$dst ;; \
|
||||
esac || exit; \
|
||||
*--) continue;; \
|
||||
esac && \
|
||||
cp $$boilerplate blt/$$dst && \
|
||||
if test -x "blt/$$dst"; then rx=rx; else rx=r; fi && \
|
||||
chmod a+$$rx "blt/$$dst" || exit; \
|
||||
done && \
|
||||
date >$@
|
||||
|
||||
|
|
|
@ -941,8 +941,17 @@ int twoway_merge(struct cache_entry **src, struct unpack_trees_options *o)
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
else if (newtree)
|
||||
else if (newtree) {
|
||||
if (oldtree && !o->initial_checkout) {
|
||||
/*
|
||||
* deletion of the path was staged;
|
||||
*/
|
||||
if (same(oldtree, newtree))
|
||||
return 1;
|
||||
return reject_merge(oldtree, o);
|
||||
}
|
||||
return merged_entry(newtree, current, o);
|
||||
}
|
||||
return deleted_entry(oldtree, current, o);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ struct unpack_trees_options {
|
|||
verbose_update:1,
|
||||
aggressive:1,
|
||||
skip_unmerged:1,
|
||||
initial_checkout:1,
|
||||
gently:1;
|
||||
const char *prefix;
|
||||
int pos;
|
||||
|
|
Loading…
Reference in a new issue