From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org, Junio C Hamano <gitster@pobox.com>,
Yann Dirson <ydirson@altern.org>
Cc: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH v2 2/2] diffcore-rename: add config option to allow to cache renames
Date: Sat, 8 Nov 2008 18:27:33 +0700 [thread overview]
Message-ID: <1226143653-3758-2-git-send-email-pclouds@gmail.com> (raw)
In-Reply-To: <1226143653-3758-1-git-send-email-pclouds@gmail.com>
If diff.cacherenames is true, then renames will be cached to
$GIT_DIR/rename-cache. By default, it will not overwrite existing
cache. Add --refresh-cache to overwrite.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/config.txt | 5 ++++
Documentation/diff-options.txt | 5 ++++
diff.c | 12 +++++++++
diff.h | 2 +
diffcore-rename.c | 49 ++++++++++++++++++++++++++++++++++++++++
t/t4031-rename-cache.sh | 36 +++++++++++++++++++++++++++++
6 files changed, 109 insertions(+), 0 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 965ed74..8a7f00e 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -630,6 +630,11 @@ diff.renames::
will enable basic rename detection. If set to "copies" or
"copy", it will detect copies, as well.
+diff.cacherenames::
+ Tells git to automatically cache renames when detected. The
+ cache resides in $GIT_DIR/rename-cache, which is used by git
+ if exists.
+
fetch.unpackLimit::
If the number of objects fetched over the git native
transfer is below this
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index c62b45c..d477a40 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -102,6 +102,11 @@ endif::git-format-patch[]
Turn off rename detection, even when the configuration
file gives the default to do so.
+--refresh-rename-cache::
+ By default, when git finds a cached version of a commit, it
+ will not overwrite the cache. This option makes git overwrite
+ old cache or create a new one.
+
--check::
Warn if changes introduce trailing whitespace
or an indent that uses a space before a tab. Exits with
diff --git a/diff.c b/diff.c
index f644947..604cb12 100644
--- a/diff.c
+++ b/diff.c
@@ -26,6 +26,7 @@ int diff_use_color_default = -1;
static const char *external_diff_cmd_cfg;
int diff_auto_refresh_index = 1;
static int diff_mnemonic_prefix;
+static int diff_cache_renames;
static char diff_colors[][COLOR_MAXLEN] = {
"\033[m", /* reset */
@@ -103,6 +104,11 @@ int git_diff_basic_config(const char *var, const char *value, void *cb)
return 0;
}
+ if (!strcmp(var, "diff.cacherenames")) {
+ diff_cache_renames = git_config_bool(var, value);
+ return 0;
+ }
+
switch (userdiff_config(var, value)) {
case 0: break;
case -1: return -1;
@@ -2272,6 +2278,8 @@ int diff_setup_done(struct diff_options *options)
if (options->detect_rename && options->rename_limit < 0)
options->rename_limit = diff_rename_limit_default;
+ if (options->detect_rename && diff_cache_renames)
+ DIFF_OPT_SET(options, CACHE_RENAMES);
if (options->setup & DIFF_SETUP_USE_CACHE) {
if (!active_cache)
/* read-cache does not die even when it fails
@@ -2439,6 +2447,10 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
DIFF_OPT_SET(options, RELATIVE_NAME);
options->prefix = arg + 11;
}
+ else if (!strcmp(arg, "--refresh-rename-cache")) {
+ DIFF_OPT_SET(options, CACHE_RENAMES);
+ DIFF_OPT_SET(options, REFRESH_RENAME_CACHE);
+ }
/* xdiff options */
else if (!strcmp(arg, "-w") || !strcmp(arg, "--ignore-all-space"))
diff --git a/diff.h b/diff.h
index 64a1edd..0503b57 100644
--- a/diff.h
+++ b/diff.h
@@ -66,6 +66,8 @@ typedef void (*diff_format_fn_t)(struct diff_queue_struct *q,
#define DIFF_OPT_DIRSTAT_CUMULATIVE (1 << 19)
#define DIFF_OPT_DIRSTAT_BY_FILE (1 << 20)
#define DIFF_OPT_ALLOW_TEXTCONV (1 << 21)
+#define DIFF_OPT_CACHE_RENAMES (1 << 22)
+#define DIFF_OPT_REFRESH_RENAME_CACHE (1 << 23)
#define DIFF_OPT_TST(opts, flag) ((opts)->flags & DIFF_OPT_##flag)
#define DIFF_OPT_SET(opts, flag) ((opts)->flags |= DIFF_OPT_##flag)
#define DIFF_OPT_CLR(opts, flag) ((opts)->flags &= ~DIFF_OPT_##flag)
diff --git a/diffcore-rename.c b/diffcore-rename.c
index 598cc8d..49651ea 100644
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
@@ -527,6 +527,44 @@ static void load_rename_cache(struct diff_queue_struct *q,
free_hash(&filepair_table);
}
+static void save_rename_cache(struct diff_queue_struct *outq,
+ struct diff_options *options)
+{
+ int i;
+ FILE *fp = NULL;
+ struct stat st;
+
+ for (i = 0;i < outq->nr; i++) {
+ struct diff_filepair *dp = outq->queue[i];
+
+ if (!(dp->renamed_pair || /* rename pair */
+ (!DIFF_FILE_VALID(dp->one) && DIFF_FILE_VALID(dp->two)))) /* create pair */
+ continue;
+
+ if (!fp) {
+ char *sha1 = sha1_to_hex(options->commit->object.sha1);
+ char *path = git_path("rename-cache/%c%c/%s", sha1[0], sha1[1], sha1+2);
+
+ /* Already cached. If not force refresh, move on */
+ if (!stat(path, &st) && !DIFF_OPT_TST(options, REFRESH_RENAME_CACHE))
+ return;
+
+ safe_create_leading_directories(path);
+ fp = fopen(path, "w");
+
+ if (!fp)
+ return;
+ }
+
+ fprintf(fp, "%s ", sha1_to_hex(dp->two->sha1));
+ fprintf(fp, "%s %d\n",
+ sha1_to_hex(DIFF_FILE_VALID(dp->one) ? dp->one->sha1 : null_sha1),
+ dp->score);
+ }
+ if (fp)
+ fclose(fp);
+}
+
void diffcore_rename(struct diff_options *options)
{
int detect_rename = options->detect_rename;
@@ -770,6 +808,17 @@ void diffcore_rename(struct diff_options *options)
}
diff_debug_queue("done copying original", &outq);
+ /*
+ * Only cache if:
+ * - Have a commit hint
+ * - diff.cacherenames is on
+ * - no pathspec limits
+ */
+ if (options->commit &&
+ DIFF_OPT_TST(options, CACHE_RENAMES) &&
+ !options->nr_paths)
+ save_rename_cache(&outq, options);
+
free(q->queue);
if (cacheq.queue)
free(cacheq.queue);
diff --git a/t/t4031-rename-cache.sh b/t/t4031-rename-cache.sh
index f7c53fd..2d3f993 100755
--- a/t/t4031-rename-cache.sh
+++ b/t/t4031-rename-cache.sh
@@ -53,4 +53,40 @@ test_expect_success 'load create pair cache' '
test_cmp expected result
'
+cat >expected <<EOF
+f2ad6c76f0115a6ba5b00456a849810e7ec0af20 0000000000000000000000000000000000000000 0
+78981922613b2afb6025042ff6bd878ac1994e85 78981922613b2afb6025042ff6bd878ac1994e85 60000
+EOF
+test_expect_success 'save rename cache' '
+ P=.git/rename-cache/$(git rev-parse HEAD|sed "s,\(..\)\(.*\),\1/\2,")
+ rm -r .git/rename-cache
+ git config diff.cacherenames true
+ git show --summary -C -M --find-copies-harder > /dev/null
+ test_cmp expected $P
+'
+
+test_expect_success 'do not save rename cache with limited pathspec' '
+ P=.git/rename-cache/$(git rev-parse HEAD|sed "s,\(..\)\(.*\),\1/\2,")
+ echo $P
+ rm $P
+ git config diff.cacherenames true
+ git log --summary -C -M --find-copies-harder HEAD -- sub
+ ! test -f $P
+'
+
+test_expect_success 'subsequent command does not change cache' '
+ P=.git/rename-cache/$(git rev-parse HEAD|sed "s,\(..\)\(.*\),\1/\2,")
+ echo corrupted > $P
+ ! test_cmp expected $P &&
+ git show --summary -C -M --find-copies-harder HEAD > /dev/null &&
+ ! test_cmp expected $P
+'
+
+test_expect_success 'overwrite cache with --refresh-rename-cache' '
+ P=.git/rename-cache/$(git rev-parse HEAD|sed "s,\(..\)\(.*\),\1/\2,")
+ ! test_cmp expected $P &&
+ git show --summary -C -M --find-copies-harder --refresh-rename-cache HEAD > /dev/null &&
+ test_cmp expected $P
+'
+
test_done
--
1.6.0.3.892.g83538
prev parent reply other threads:[~2008-11-08 11:30 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-11-08 11:27 [PATCH v2 1/2] diffcore-rename: support rename cache Nguyễn Thái Ngọc Duy
2008-11-08 11:27 ` Nguyễn Thái Ngọc Duy [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1226143653-3758-2-git-send-email-pclouds@gmail.com \
--to=pclouds@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=ydirson@altern.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox