From d78b0f3d6aa04510dd0c22c3853d3954c5f5b531 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Wed, 16 Aug 2006 10:44:02 +0200 Subject: [PATCH 1/7] [PATCH] git-mv: add more path normalization We already use the normalization from get_pathspec(), but now we also remove a trailing slash. So, git mv some_path/ into_some_path/ works now. Also, move the "can not move directory into itself" test before the subdirectory expansion. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- builtin-mv.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/builtin-mv.c b/builtin-mv.c index e7b5eb7088..c0c8764f7f 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -17,12 +17,19 @@ static const char builtin_mv_usage[] = static const char **copy_pathspec(const char *prefix, const char **pathspec, int count, int base_name) { + int i; const char **result = xmalloc((count + 1) * sizeof(const char *)); memcpy(result, pathspec, count * sizeof(const char *)); result[count] = NULL; - if (base_name) { - int i; - for (i = 0; i < count; i++) { + for (i = 0; i < count; i++) { + int length = strlen(result[i]); + if (length > 0 && result[i][length - 1] == '/') { + char *without_slash = xmalloc(length); + memcpy(without_slash, result[i], length - 1); + without_slash[length] = '\0'; + result[i] = without_slash; + } + if (base_name) { const char *last_slash = strrchr(result[i], '/'); if (last_slash) result[i] = last_slash + 1; @@ -129,6 +136,12 @@ int cmd_mv(int argc, const char **argv, const char *prefix) if (lstat(source[i], &st) < 0) bad = "bad source"; + if (!bad && + (length = strlen(source[i])) >= 0 && + !strncmp(destination[i], source[i], length) && + (destination[i][length] == 0 || destination[i][length] == '/')) + bad = "can not move directory into itself"; + if (S_ISDIR(st.st_mode)) { const char *dir = source[i], *dest_dir = destination[i]; int first, last, len = strlen(dir); @@ -204,12 +217,6 @@ int cmd_mv(int argc, const char **argv, const char *prefix) } } - if (!bad && - (length = strlen(source[i])) >= 0 && - !strncmp(destination[i], source[i], length) && - (destination[i][length] == 0 || destination[i][length] == '/')) - bad = "can not move directory into itself"; - if (!bad && cache_name_pos(source[i], strlen(source[i])) < 0) bad = "not under version control"; From e79ca7cc25755ac1a3be921f30630f4f064bf862 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Wed, 16 Aug 2006 14:50:34 +0200 Subject: [PATCH 2/7] gitweb: Add support for per project git URLs It is now possible for project to have individual clone/fetch URLs. They are provided in new file 'cloneurl' added below project's $GIT_DIR directory. If there is no cloneurl file, concatenation of git base URLs with project name is used. This is merge of Jakub Narebski and David Rientjes gitweb: Show project's git URL on summary page with Aneesh Kumar gitweb: Add support for cloneurl. gitweb: Support multiple clone urls patches. Signed-off-by: Jakub Narebski Signed-off-by: Aneesh Kumar K.V Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 37a6284fc4..7c92ac30ce 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -533,6 +533,16 @@ sub git_get_project_description { return $descr; } +sub git_get_project_url_list { + my $path = shift; + + open my $fd, "$projectroot/$path/cloneurl" or return undef; + my @git_project_url_list = map { chomp; $_ } <$fd>; + close $fd; + + return wantarray ? @git_project_url_list : \@git_project_url_list; +} + sub git_get_projects_list { my @list; @@ -1697,10 +1707,14 @@ sub git_summary { "description" . esc_html($descr) . "\n" . "owner$owner\n" . "last change$cd{'rfc2822'}\n"; + # use per project git URL list in $projectroot/$project/cloneurl + # or make project git URL from git base URL and project name my $url_tag = "URL"; - foreach my $git_base_url (@git_base_url_list) { - next unless $git_base_url; - print "$url_tag$git_base_url/$project\n"; + my @url_list = git_get_project_url_list($project); + @url_list = map { "$_/$project" } @git_base_url_list unless @url_list; + foreach my $git_url (@url_list) { + next unless $git_url; + print "$url_tag$git_url\n"; $url_tag = ""; } print "\n"; From 6493cc09c2aa626ffbe6024dd705e1495c2d87e4 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 16 Aug 2006 13:58:32 -0700 Subject: [PATCH 3/7] builtin-grep: remove unused debugging cruft. Signed-off-by: Junio C Hamano --- builtin-grep.c | 57 -------------------------------------------------- 1 file changed, 57 deletions(-) diff --git a/builtin-grep.c b/builtin-grep.c index 3ec99b7010..0bd517b264 100644 --- a/builtin-grep.c +++ b/builtin-grep.c @@ -175,61 +175,12 @@ static void compile_regexp(struct grep_pat *p, struct grep_opt *opt) } } -#if DEBUG -static inline void indent(int in) -{ - int i; - for (i = 0; i < in; i++) putchar(' '); -} - -static void dump_pattern_exp(struct grep_expr *x, int in) -{ - switch (x->node) { - case GREP_NODE_ATOM: - indent(in); - puts(x->u.atom->pattern); - break; - case GREP_NODE_NOT: - indent(in); - puts("--not"); - dump_pattern_exp(x->u.unary, in+1); - break; - case GREP_NODE_AND: - dump_pattern_exp(x->u.binary.left, in+1); - indent(in); - puts("--and"); - dump_pattern_exp(x->u.binary.right, in+1); - break; - case GREP_NODE_OR: - dump_pattern_exp(x->u.binary.left, in+1); - indent(in); - puts("--or"); - dump_pattern_exp(x->u.binary.right, in+1); - break; - } -} - -static void looking_at(const char *msg, struct grep_pat **list) -{ - struct grep_pat *p = *list; - fprintf(stderr, "%s: looking at ", msg); - if (!p) - fprintf(stderr, "empty\n"); - else - fprintf(stderr, "<%s>\n", p->pattern); -} -#else -#define looking_at(a,b) do {} while(0) -#endif - static struct grep_expr *compile_pattern_expr(struct grep_pat **); static struct grep_expr *compile_pattern_atom(struct grep_pat **list) { struct grep_pat *p; struct grep_expr *x; - looking_at("atom", list); - p = *list; switch (p->token) { case GREP_PATTERN: /* atom */ @@ -257,8 +208,6 @@ static struct grep_expr *compile_pattern_not(struct grep_pat **list) struct grep_pat *p; struct grep_expr *x; - looking_at("not", list); - p = *list; switch (p->token) { case GREP_NOT: @@ -281,8 +230,6 @@ static struct grep_expr *compile_pattern_and(struct grep_pat **list) struct grep_pat *p; struct grep_expr *x, *y, *z; - looking_at("and", list); - x = compile_pattern_not(list); p = *list; if (p && p->token == GREP_AND) { @@ -306,8 +253,6 @@ static struct grep_expr *compile_pattern_or(struct grep_pat **list) struct grep_pat *p; struct grep_expr *x, *y, *z; - looking_at("or", list); - x = compile_pattern_and(list); p = *list; if (x && p && p->token != GREP_CLOSE_PAREN) { @@ -325,8 +270,6 @@ static struct grep_expr *compile_pattern_or(struct grep_pat **list) static struct grep_expr *compile_pattern_expr(struct grep_pat **list) { - looking_at("expr", list); - return compile_pattern_or(list); } From 076a10c7282a08f783a28c1b64d0e114a3fe3d39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Skytt=C3=A4?= Date: Wed, 16 Aug 2006 23:12:26 +0300 Subject: [PATCH 4/7] Be nicer if git executable is not installed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch avoids problems if vc-git.el is installed and activated, but the git executable is not available, for example http://list-archive.xemacs.org/xemacs-beta/200608/msg00062.html Signed-off-by: Ville Skyttä Signed-off-by: Junio C Hamano --- contrib/emacs/vc-git.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/emacs/vc-git.el b/contrib/emacs/vc-git.el index 3f6ed699f0..4a8f79092d 100644 --- a/contrib/emacs/vc-git.el +++ b/contrib/emacs/vc-git.el @@ -54,7 +54,7 @@ (let* ((dir (file-name-directory file)) (name (file-relative-name file dir))) (when dir (cd dir)) - (and (eq 0 (call-process "git" nil '(t nil) nil "ls-files" "-c" "-z" "--" name)) + (and (ignore-errors (eq 0 (call-process "git" nil '(t nil) nil "ls-files" "-c" "-z" "--" name))) (let ((str (buffer-string))) (and (> (length str) (length name)) (string= (substring str 0 (1+ (length name))) (concat name "\0")))))))) From 03eb8f8aeb8a483b11b797cca012fdded818a5c1 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 16 Aug 2006 16:07:20 -0700 Subject: [PATCH 5/7] builtin-apply --reverse: two bugfixes. Parsing of a binary hunk did not consume the terminating blank line. When applying in reverse, it did not use the second, reverse binary hunk. Signed-off-by: Junio C Hamano --- builtin-apply.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/builtin-apply.c b/builtin-apply.c index 4f0eef0ac3..be6e94d367 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -1063,8 +1063,12 @@ static struct fragment *parse_binary_hunk(char **buf_p, llen = linelen(buffer, size); used += llen; linenr++; - if (llen == 1) + if (llen == 1) { + /* consume the blank line */ + buffer++; + size--; break; + } /* Minimum line is "A00000\n" which is 7-byte long, * and the line length must be multiple of 5 plus 2. */ @@ -1618,7 +1622,7 @@ static int apply_binary_fragment(struct buffer_desc *desc, struct patch *patch) "without the reverse hunk to '%s'", patch->new_name ? patch->new_name : patch->old_name); - fragment = fragment; + fragment = fragment->next; } data = (void*) fragment->patch; switch (fragment->binary_patch_method) { @@ -1717,7 +1721,7 @@ static int apply_binary(struct buffer_desc *desc, struct patch *patch) write_sha1_file_prepare(desc->buffer, desc->size, blob_type, sha1, hdr, &hdrlen); if (strcmp(sha1_to_hex(sha1), patch->new_sha1_prefix)) - return error("binary patch to '%s' creates incorrect result", name); + return error("binary patch to '%s' creates incorrect result (expecting %s, got %s)", name, patch->new_sha1_prefix, sha1_to_hex(sha1)); } return 0; From d4c452f03b49072ebb46fc524e6d85056a35ef13 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 16 Aug 2006 16:08:14 -0700 Subject: [PATCH 6/7] diff.c: make binary patch reversible. This matches the format previous "git-apply --reverse" update expects. Signed-off-by: Junio C Hamano --- diff.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/diff.c b/diff.c index 7a238d0233..b8161960e6 100644 --- a/diff.c +++ b/diff.c @@ -838,7 +838,7 @@ static unsigned char *deflate_it(char *data, return deflated; } -static void emit_binary_diff(mmfile_t *one, mmfile_t *two) +static void emit_binary_diff_body(mmfile_t *one, mmfile_t *two) { void *cp; void *delta; @@ -849,7 +849,6 @@ static void emit_binary_diff(mmfile_t *one, mmfile_t *two) unsigned long deflate_size; unsigned long data_size; - printf("GIT binary patch\n"); /* We could do deflated delta, or we could do just deflated two, * whichever is smaller. */ @@ -898,6 +897,13 @@ static void emit_binary_diff(mmfile_t *one, mmfile_t *two) free(data); } +static void emit_binary_diff(mmfile_t *one, mmfile_t *two) +{ + printf("GIT binary patch\n"); + emit_binary_diff_body(one, two); + emit_binary_diff_body(two, one); +} + #define FIRST_FEW_BYTES 8000 static int mmfile_is_binary(mmfile_t *mf) { From 2cda1a214e9d2e362242027b4b622ecb3d9260de Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 16 Aug 2006 16:09:25 -0700 Subject: [PATCH 7/7] apply --reverse: tie it all together. Add a few tests, usage string, and documentation. Signed-off-by: Junio C Hamano --- Documentation/git-apply.txt | 6 ++++- builtin-apply.c | 2 +- t/t4116-apply-reverse.sh | 47 +++++++++++++++++++++++++++++++++---- 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/Documentation/git-apply.txt b/Documentation/git-apply.txt index 2ff74949a7..f1ab1f9da5 100644 --- a/Documentation/git-apply.txt +++ b/Documentation/git-apply.txt @@ -10,7 +10,8 @@ SYNOPSIS -------- [verse] 'git-apply' [--stat] [--numstat] [--summary] [--check] [--index] [--apply] - [--no-add] [--index-info] [--allow-binary-replacement] [-z] [-pNUM] + [--no-add] [--index-info] [--allow-binary-replacement] + [--reverse] [-z] [-pNUM] [-CNUM] [--whitespace=] [...] @@ -62,6 +63,9 @@ OPTIONS the original version of the blob is available locally, outputs information about them to the standard output. +--reverse:: + Apply the patch in reverse. + -z:: When showing the index information, do not munge paths, but use NUL terminated machine readable format. Without diff --git a/builtin-apply.c b/builtin-apply.c index be6e94d367..4737b64c32 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -43,7 +43,7 @@ static int show_index_info; static int line_termination = '\n'; static unsigned long p_context = -1; static const char apply_usage[] = -"git-apply [--stat] [--numstat] [--summary] [--check] [--index] [--cached] [--apply] [--no-add] [--index-info] [--allow-binary-replacement] [-z] [-pNUM] [-CNUM] [--whitespace=] ..."; +"git-apply [--stat] [--numstat] [--summary] [--check] [--index] [--cached] [--apply] [--no-add] [--index-info] [--allow-binary-replacement] [--reverse] [-z] [-pNUM] [-CNUM] [--whitespace=] ..."; static enum whitespace_eol { nowarn_whitespace, diff --git a/t/t4116-apply-reverse.sh b/t/t4116-apply-reverse.sh index 69aebe6005..74f5c2a575 100755 --- a/t/t4116-apply-reverse.sh +++ b/t/t4116-apply-reverse.sh @@ -22,25 +22,64 @@ test_expect_success setup ' tr "[mon]" '\''[\0\1\2]'\'' file2 && git commit -a -m second && + git tag second && - git diff --binary -R initial >patch + git diff --binary initial second >patch ' test_expect_success 'apply in forward' ' + T0=`git rev-parse "second^{tree}"` && + git reset --hard initial && git apply --index --binary patch && - git diff initial >diff && - diff -u /dev/null diff - + T1=`git write-tree` && + test "$T0" = "$T1" ' test_expect_success 'apply in reverse' ' + git reset --hard second && git apply --reverse --binary --index patch && git diff >diff && diff -u /dev/null diff ' +test_expect_success 'setup separate repository lacking postimage' ' + + git tar-tree initial initial | tar xf - && + ( + cd initial && git init-db && git add . + ) && + + git tar-tree second second | tar xf - && + ( + cd second && git init-db && git add . + ) + +' + +test_expect_success 'apply in forward without postimage' ' + + T0=`git rev-parse "second^{tree}"` && + ( + cd initial && + git apply --index --binary ../patch && + T1=`git write-tree` && + test "$T0" = "$T1" + ) +' + +test_expect_success 'apply in reverse without postimage' ' + + T0=`git rev-parse "initial^{tree}"` && + ( + cd second && + git apply --index --binary --reverse ../patch && + T1=`git write-tree` && + test "$T0" = "$T1" + ) +' + test_done