* [PATCH] git-rerere.txt: Mention rr-cache directory
@ 2008-07-09 0:17 Stephan Beyer
2008-07-09 0:25 ` Johannes Schindelin
0 siblings, 1 reply; 11+ messages in thread
From: Stephan Beyer @ 2008-07-09 0:17 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Stephan Beyer
If a user reads the rerere documentation, he or she is not told to
create the $GIT_DIR/rr-cache directory to be able to use git-rerere.
This patch adds such a remark.
Signed-off-by: Stephan Beyer <s-beyer@gmx.net>
---
Documentation/git-rerere.txt | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/Documentation/git-rerere.txt b/Documentation/git-rerere.txt
index 678bfd3..667505c 100644
--- a/Documentation/git-rerere.txt
+++ b/Documentation/git-rerere.txt
@@ -23,8 +23,8 @@ initial manual merge, and later by noticing the same automerge
results and applying the previously recorded hand resolution.
[NOTE]
-You need to set the configuration variable rerere.enabled to
-enable this command.
+You need to set the configuration variable `rerere.enabled` and create
+the `rr-cache` directory under `$GIT_DIR` to enable this command.
COMMANDS
@@ -170,8 +170,8 @@ As a convenience measure, 'git-merge' automatically invokes
records it if it is a new conflict, or reuses the earlier hand
resolve when it is not. 'git-commit' also invokes 'git-rerere'
when recording a merge result. What this means is that you do
-not have to do anything special yourself (Note: you still have
-to set the config variable rerere.enabled to enable this command).
+not have to do anything special yourself, except making sure
+that `rerere.enabled` is set and `$GIT_DIR/rr-cache` exists.
In our example, when you did the test merge, the manual
resolution is recorded, and it will be reused when you do the
--
1.5.6.2.574.gd4568
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH] git-rerere.txt: Mention rr-cache directory
2008-07-09 0:17 [PATCH] git-rerere.txt: Mention rr-cache directory Stephan Beyer
@ 2008-07-09 0:25 ` Johannes Schindelin
2008-07-09 0:38 ` Johannes Schindelin
0 siblings, 1 reply; 11+ messages in thread
From: Johannes Schindelin @ 2008-07-09 0:25 UTC (permalink / raw)
To: Stephan Beyer; +Cc: Junio C Hamano, git
Hi,
On Wed, 9 Jul 2008, Stephan Beyer wrote:
> If a user reads the rerere documentation, he or she is not told to
> create the $GIT_DIR/rr-cache directory to be able to use git-rerere.
Is it? The config setting is not enough? Then that is a bug, and should
not be blessed by a bug in the documentation.
Ciao,
Dscho
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] git-rerere.txt: Mention rr-cache directory
2008-07-09 0:25 ` Johannes Schindelin
@ 2008-07-09 0:38 ` Johannes Schindelin
2008-07-09 1:09 ` Junio C Hamano
` (2 more replies)
0 siblings, 3 replies; 11+ messages in thread
From: Johannes Schindelin @ 2008-07-09 0:38 UTC (permalink / raw)
To: Stephan Beyer; +Cc: Junio C Hamano, git
Hi,
On Wed, 9 Jul 2008, Johannes Schindelin wrote:
> On Wed, 9 Jul 2008, Stephan Beyer wrote:
>
> > If a user reads the rerere documentation, he or she is not told to
> > create the $GIT_DIR/rr-cache directory to be able to use git-rerere.
>
> Is it? The config setting is not enough? Then that is a bug, and should
> not be blessed by a bug in the documentation.
Okay, I took a look:
-- snip --
static int is_rerere_enabled(void)
{
struct stat st;
const char *rr_cache;
int rr_cache_exists;
if (!rerere_enabled)
return 0;
rr_cache = git_path("rr-cache");
rr_cache_exists = !stat(rr_cache, &st) && S_ISDIR(st.st_mode);
if (rerere_enabled < 0)
return rr_cache_exists;
if (!rr_cache_exists &&
(mkdir(rr_cache, 0777) || adjust_shared_perm(rr_cache)))
die("Could not create directory %s", rr_cache);
return 1;
}
-- snap --
As you can see, in the case rerere_enabled < 0 (i.e. the config did not
say anything about rerere), it is assumed enabled _exactly_ when
.git/rr_cache/ exists.
But if it is > 0, the directory is created.
Of course, this only holds true when the config is read, i.e. when
setup_rerere() was called in time. Which is the case when you call
rerere() (as is done both from cmd_rerere() as well as cmd_commit()).
Of course, I haven't tested it. Other than running the test script, that
is.
So care to elaborate what is going wrong?
BTW I think it is a horrible thing that rerere() is declared in commit.h
(a libgit header), but implemented in builtin-rerere.c, which is not part
of libgit.a.
Ciao,
Dscho
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] git-rerere.txt: Mention rr-cache directory
2008-07-09 0:38 ` Johannes Schindelin
@ 2008-07-09 1:09 ` Junio C Hamano
2008-07-09 9:21 ` Stephan Beyer
2008-07-09 10:18 ` [PATCH] rerere: Separate libgit and builtin functions Stephan Beyer
2 siblings, 0 replies; 11+ messages in thread
From: Junio C Hamano @ 2008-07-09 1:09 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Stephan Beyer, git
Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> Of course, this only holds true when the config is read, i.e. when
> setup_rerere() was called in time. Which is the case when you call
> rerere() (as is done both from cmd_rerere() as well as cmd_commit()).
>
> Of course, I haven't tested it. Other than running the test script, that
> is.
>
> So care to elaborate what is going wrong?
Very interesting question indeed.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] git-rerere.txt: Mention rr-cache directory
2008-07-09 0:38 ` Johannes Schindelin
2008-07-09 1:09 ` Junio C Hamano
@ 2008-07-09 9:21 ` Stephan Beyer
2008-07-09 10:18 ` [PATCH] rerere: Separate libgit and builtin functions Stephan Beyer
2 siblings, 0 replies; 11+ messages in thread
From: Stephan Beyer @ 2008-07-09 9:21 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Junio C Hamano, git
Hi,
On Wed, Jul 09, Johannes Schindelin wrote:
> On Wed, 9 Jul 2008, Johannes Schindelin wrote:
> > On Wed, 9 Jul 2008, Stephan Beyer wrote:
> >
> > > If a user reads the rerere documentation, he or she is not told to
> > > create the $GIT_DIR/rr-cache directory to be able to use git-rerere.
> >
> > Is it? The config setting is not enough? Then that is a bug, and should
> > not be blessed by a bug in the documentation.
I don't know if this is exactly a bug, at least config.txt says:
rerere.enabled::
Activate recording of resolved conflicts, so that identical
conflict hunks can be resolved automatically, should they
be encountered again. linkgit:git-rerere[1] command is by
default enabled if you create `rr-cache` directory under
`$GIT_DIR`, but can be disabled by setting this option to false.
So according to *that* documentation it is right, according to the
git-rerere.txt documentation it was wrong, and according to the
source it is...
> -- snip --
> static int is_rerere_enabled(void)
> {
> struct stat st;
> const char *rr_cache;
> int rr_cache_exists;
>
> if (!rerere_enabled)
> return 0;
>
> rr_cache = git_path("rr-cache");
> rr_cache_exists = !stat(rr_cache, &st) && S_ISDIR(st.st_mode);
> if (rerere_enabled < 0)
> return rr_cache_exists;
>
> if (!rr_cache_exists &&
> (mkdir(rr_cache, 0777) || adjust_shared_perm(rr_cache)))
> die("Could not create directory %s", rr_cache);
> return 1;
> }
> -- snap --
>
> As you can see, in the case rerere_enabled < 0 (i.e. the config did not
> say anything about rerere), it is assumed enabled _exactly_ when
> .git/rr_cache/ exists.
>
> But if it is > 0, the directory is created.
Yes.
There is also an important part in the file:
-- snip --
/* if rerere_enabled == -1, fall back to detection of .git/rr-cache */
static int rerere_enabled = -1;
-- snap --
So this means it's the following behavior:
- rerere_enabled < 0: enable, iff rr-cache exists
- rerere_enabled ==0: disable
- rerere_enabled > 0: enable and create rr-cache if it does not exist
So this is my fault, sorry :) Both documentations (config.txt and
git-rerere.txt) are right.
It was not explicitly enabled on this one machine which lead me to the
wrong assumption. I should sync my ~/.gitconfig more often ;)
Sorry for that,
Stephan
--
Stephan Beyer <s-beyer@gmx.net>, PGP 0x6EDDD207FCC5040F
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH] rerere: Separate libgit and builtin functions
2008-07-09 0:38 ` Johannes Schindelin
2008-07-09 1:09 ` Junio C Hamano
2008-07-09 9:21 ` Stephan Beyer
@ 2008-07-09 10:18 ` Stephan Beyer
2008-07-09 11:55 ` Johannes Schindelin
2008-07-09 12:03 ` [PATCH] " Johannes Schindelin
2 siblings, 2 replies; 11+ messages in thread
From: Stephan Beyer @ 2008-07-09 10:18 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git, Junio C Hamano, Stephan Beyer
This patch moves rerere()-related functions into a newly created
rerere.c file. Also setup_rerere() is moved into rerere.c to decrease
code duplications for rerere.c and builtin-rerere.c.
Signed-off-by: Stephan Beyer <s-beyer@gmx.net>
---
> BTW I think it is a horrible thing that rerere() is declared in commit.h
> (a libgit header), but implemented in builtin-rerere.c, which is not part
> of libgit.a.
Ok, I give it a try.
Makefile | 2 +
builtin-rerere.c | 324 +++---------------------------------------
builtin-rerere.c => rerere.c | 133 +-----------------
rerere.h | 9 ++
4 files changed, 32 insertions(+), 436 deletions(-)
copy builtin-rerere.c => rerere.c (66%)
create mode 100644 rerere.h
diff --git a/Makefile b/Makefile
index bddd1a7..4e23c29 100644
--- a/Makefile
+++ b/Makefile
@@ -363,6 +363,7 @@ LIB_H += quote.h
LIB_H += reflog-walk.h
LIB_H += refs.h
LIB_H += remote.h
+LIB_H += rerere.h
LIB_H += revision.h
LIB_H += run-command.h
LIB_H += sha1-lookup.h
@@ -447,6 +448,7 @@ LIB_OBJS += read-cache.o
LIB_OBJS += reflog-walk.o
LIB_OBJS += refs.o
LIB_OBJS += remote.o
+LIB_OBJS += rerere.o
LIB_OBJS += revision.o
LIB_OBJS += run-command.o
LIB_OBJS += server-info.o
diff --git a/builtin-rerere.c b/builtin-rerere.c
index 85222d9..669a963 100644
--- a/builtin-rerere.c
+++ b/builtin-rerere.c
@@ -1,6 +1,7 @@
#include "builtin.h"
#include "cache.h"
#include "path-list.h"
+#include "rerere.h"
#include "xdiff/xdiff.h"
#include "xdiff-interface.h"
@@ -13,183 +14,11 @@ static const char git_rerere_usage[] =
static int cutoff_noresolve = 15;
static int cutoff_resolve = 60;
-/* if rerere_enabled == -1, fall back to detection of .git/rr-cache */
-static int rerere_enabled = -1;
-
-static char *merge_rr_path;
-
static const char *rr_path(const char *name, const char *file)
{
return git_path("rr-cache/%s/%s", name, file);
}
-static void read_rr(struct path_list *rr)
-{
- unsigned char sha1[20];
- char buf[PATH_MAX];
- FILE *in = fopen(merge_rr_path, "r");
- if (!in)
- return;
- while (fread(buf, 40, 1, in) == 1) {
- int i;
- char *name;
- if (get_sha1_hex(buf, sha1))
- die("corrupt MERGE_RR");
- buf[40] = '\0';
- name = xstrdup(buf);
- if (fgetc(in) != '\t')
- die("corrupt MERGE_RR");
- for (i = 0; i < sizeof(buf) && (buf[i] = fgetc(in)); i++)
- ; /* do nothing */
- if (i == sizeof(buf))
- die("filename too long");
- path_list_insert(buf, rr)->util = name;
- }
- fclose(in);
-}
-
-static struct lock_file write_lock;
-
-static int write_rr(struct path_list *rr, int out_fd)
-{
- int i;
- for (i = 0; i < rr->nr; i++) {
- const char *path = rr->items[i].path;
- int length = strlen(path) + 1;
- if (write_in_full(out_fd, rr->items[i].util, 40) != 40 ||
- write_in_full(out_fd, "\t", 1) != 1 ||
- write_in_full(out_fd, path, length) != length)
- die("unable to write rerere record");
- }
- if (commit_lock_file(&write_lock) != 0)
- die("unable to write rerere record");
- return 0;
-}
-
-static int handle_file(const char *path,
- unsigned char *sha1, const char *output)
-{
- SHA_CTX ctx;
- char buf[1024];
- int hunk = 0, hunk_no = 0;
- struct strbuf one, two;
- FILE *f = fopen(path, "r");
- FILE *out = NULL;
-
- if (!f)
- return error("Could not open %s", path);
-
- if (output) {
- out = fopen(output, "w");
- if (!out) {
- fclose(f);
- return error("Could not write %s", output);
- }
- }
-
- if (sha1)
- SHA1_Init(&ctx);
-
- strbuf_init(&one, 0);
- strbuf_init(&two, 0);
- while (fgets(buf, sizeof(buf), f)) {
- if (!prefixcmp(buf, "<<<<<<< "))
- hunk = 1;
- else if (!prefixcmp(buf, "======="))
- hunk = 2;
- else if (!prefixcmp(buf, ">>>>>>> ")) {
- int cmp = strbuf_cmp(&one, &two);
-
- hunk_no++;
- hunk = 0;
- if (cmp > 0) {
- strbuf_swap(&one, &two);
- }
- if (out) {
- fputs("<<<<<<<\n", out);
- fwrite(one.buf, one.len, 1, out);
- fputs("=======\n", out);
- fwrite(two.buf, two.len, 1, out);
- fputs(">>>>>>>\n", out);
- }
- if (sha1) {
- SHA1_Update(&ctx, one.buf ? one.buf : "",
- one.len + 1);
- SHA1_Update(&ctx, two.buf ? two.buf : "",
- two.len + 1);
- }
- strbuf_reset(&one);
- strbuf_reset(&two);
- } else if (hunk == 1)
- strbuf_addstr(&one, buf);
- else if (hunk == 2)
- strbuf_addstr(&two, buf);
- else if (out)
- fputs(buf, out);
- }
- strbuf_release(&one);
- strbuf_release(&two);
-
- fclose(f);
- if (out)
- fclose(out);
- if (sha1)
- SHA1_Final(sha1, &ctx);
- return hunk_no;
-}
-
-static int find_conflict(struct path_list *conflict)
-{
- int i;
- if (read_cache() < 0)
- return error("Could not read index");
- for (i = 0; i+1 < active_nr; i++) {
- struct cache_entry *e2 = active_cache[i];
- struct cache_entry *e3 = active_cache[i+1];
- if (ce_stage(e2) == 2 &&
- ce_stage(e3) == 3 &&
- ce_same_name(e2, e3) &&
- S_ISREG(e2->ce_mode) &&
- S_ISREG(e3->ce_mode)) {
- path_list_insert((const char *)e2->name, conflict);
- i++; /* skip over both #2 and #3 */
- }
- }
- return 0;
-}
-
-static int merge(const char *name, const char *path)
-{
- int ret;
- mmfile_t cur, base, other;
- mmbuffer_t result = {NULL, 0};
- xpparam_t xpp = {XDF_NEED_MINIMAL};
-
- if (handle_file(path, NULL, rr_path(name, "thisimage")) < 0)
- return 1;
-
- if (read_mmfile(&cur, rr_path(name, "thisimage")) ||
- read_mmfile(&base, rr_path(name, "preimage")) ||
- read_mmfile(&other, rr_path(name, "postimage")))
- return 1;
- ret = xdl_merge(&base, &cur, "", &other, "",
- &xpp, XDL_MERGE_ZEALOUS, &result);
- if (!ret) {
- FILE *f = fopen(path, "w");
- if (!f)
- return error("Could not write to %s", path);
- fwrite(result.ptr, result.size, 1, f);
- fclose(f);
- }
-
- free(cur.ptr);
- free(base.ptr);
- free(other.ptr);
- free(result.ptr);
-
- return ret;
-}
-
static void unlink_rr_item(const char *name)
{
unlink(rr_path(name, "thisimage"));
@@ -198,6 +27,17 @@ static void unlink_rr_item(const char *name)
rmdir(git_path("rr-cache/%s", name));
}
+static int git_rerere_gc_config(const char *var, const char *value, void *cb)
+{
+ if (!strcmp(var, "gc.rerereresolved"))
+ cutoff_resolve = git_config_int(var, value);
+ else if (!strcmp(var, "gc.rerereunresolved"))
+ cutoff_noresolve = git_config_int(var, value);
+ else
+ return git_default_config(var, value, cb);
+ return 0;
+}
+
static void garbage_collect(struct path_list *rr)
{
struct path_list to_remove = { NULL, 0, 0, 1 };
@@ -207,6 +47,7 @@ static void garbage_collect(struct path_list *rr)
int len, i, cutoff;
time_t now = time(NULL), then;
+ git_config(git_rerere_gc_config, NULL);
strlcpy(buf, git_path("rr-cache"), sizeof(buf));
len = strlen(buf);
dir = opendir(buf);
@@ -267,148 +108,19 @@ static int diff_two(const char *file1, const char *label1,
return 0;
}
-static int do_plain_rerere(struct path_list *rr, int fd)
-{
- struct path_list conflict = { NULL, 0, 0, 1 };
- int i;
-
- find_conflict(&conflict);
-
- /*
- * MERGE_RR records paths with conflicts immediately after merge
- * failed. Some of the conflicted paths might have been hand resolved
- * in the working tree since then, but the initial run would catch all
- * and register their preimages.
- */
-
- for (i = 0; i < conflict.nr; i++) {
- const char *path = conflict.items[i].path;
- if (!path_list_has_path(rr, path)) {
- unsigned char sha1[20];
- char *hex;
- int ret;
- ret = handle_file(path, sha1, NULL);
- if (ret < 1)
- continue;
- hex = xstrdup(sha1_to_hex(sha1));
- path_list_insert(path, rr)->util = hex;
- if (mkdir(git_path("rr-cache/%s", hex), 0755))
- continue;;
- handle_file(path, NULL, rr_path(hex, "preimage"));
- fprintf(stderr, "Recorded preimage for '%s'\n", path);
- }
- }
-
- /*
- * Now some of the paths that had conflicts earlier might have been
- * hand resolved. Others may be similar to a conflict already that
- * was resolved before.
- */
-
- for (i = 0; i < rr->nr; i++) {
- struct stat st;
- int ret;
- const char *path = rr->items[i].path;
- const char *name = (const char *)rr->items[i].util;
-
- if (!stat(rr_path(name, "preimage"), &st) &&
- !stat(rr_path(name, "postimage"), &st)) {
- if (!merge(name, path)) {
- fprintf(stderr, "Resolved '%s' using "
- "previous resolution.\n", path);
- goto tail_optimization;
- }
- }
-
- /* Let's see if we have resolved it. */
- ret = handle_file(path, NULL, NULL);
- if (ret)
- continue;
-
- fprintf(stderr, "Recorded resolution for '%s'.\n", path);
- copy_file(rr_path(name, "postimage"), path, 0666);
-tail_optimization:
- if (i < rr->nr - 1)
- memmove(rr->items + i,
- rr->items + i + 1,
- sizeof(rr->items[0]) * (rr->nr - i - 1));
- rr->nr--;
- i--;
- }
-
- return write_rr(rr, fd);
-}
-
-static int git_rerere_config(const char *var, const char *value, void *cb)
-{
- if (!strcmp(var, "gc.rerereresolved"))
- cutoff_resolve = git_config_int(var, value);
- else if (!strcmp(var, "gc.rerereunresolved"))
- cutoff_noresolve = git_config_int(var, value);
- else if (!strcmp(var, "rerere.enabled"))
- rerere_enabled = git_config_bool(var, value);
- else
- return git_default_config(var, value, cb);
- return 0;
-}
-
-static int is_rerere_enabled(void)
-{
- struct stat st;
- const char *rr_cache;
- int rr_cache_exists;
-
- if (!rerere_enabled)
- return 0;
-
- rr_cache = git_path("rr-cache");
- rr_cache_exists = !stat(rr_cache, &st) && S_ISDIR(st.st_mode);
- if (rerere_enabled < 0)
- return rr_cache_exists;
-
- if (!rr_cache_exists &&
- (mkdir(rr_cache, 0777) || adjust_shared_perm(rr_cache)))
- die("Could not create directory %s", rr_cache);
- return 1;
-}
-
-static int setup_rerere(struct path_list *merge_rr)
-{
- int fd;
-
- git_config(git_rerere_config, NULL);
- if (!is_rerere_enabled())
- return -1;
-
- merge_rr_path = xstrdup(git_path("rr-cache/MERGE_RR"));
- fd = hold_lock_file_for_update(&write_lock, merge_rr_path, 1);
- read_rr(merge_rr);
- return fd;
-}
-
-int rerere(void)
-{
- struct path_list merge_rr = { NULL, 0, 0, 1 };
- int fd;
-
- fd = setup_rerere(&merge_rr);
- if (fd < 0)
- return 0;
- return do_plain_rerere(&merge_rr, fd);
-}
-
int cmd_rerere(int argc, const char **argv, const char *prefix)
{
struct path_list merge_rr = { NULL, 0, 0, 1 };
int i, fd;
+ if (argc < 2)
+ return rerere();
+
fd = setup_rerere(&merge_rr);
if (fd < 0)
return 0;
- if (argc < 2)
- return do_plain_rerere(&merge_rr, fd);
- else if (!strcmp(argv[1], "clear")) {
+ if (!strcmp(argv[1], "clear")) {
for (i = 0; i < merge_rr.nr; i++) {
struct stat st;
const char *name = (const char *)merge_rr.items[i].util;
@@ -417,7 +129,7 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)
stat(rr_path(name, "postimage"), &st))
unlink_rr_item(name);
}
- unlink(merge_rr_path);
+ unlink(git_path("rr-cache/MERGE_RR"));
} else if (!strcmp(argv[1], "gc"))
garbage_collect(&merge_rr);
else if (!strcmp(argv[1], "status"))
diff --git a/builtin-rerere.c b/rerere.c
similarity index 66%
copy from builtin-rerere.c
copy to rerere.c
index 85222d9..5c22bed 100644
--- a/builtin-rerere.c
+++ b/rerere.c
@@ -1,18 +1,11 @@
-#include "builtin.h"
#include "cache.h"
#include "path-list.h"
+#include "rerere.h"
#include "xdiff/xdiff.h"
#include "xdiff-interface.h"
#include <time.h>
-static const char git_rerere_usage[] =
-"git-rerere [clear | status | diff | gc]";
-
-/* these values are days */
-static int cutoff_noresolve = 15;
-static int cutoff_resolve = 60;
-
/* if rerere_enabled == -1, fall back to detection of .git/rr-cache */
static int rerere_enabled = -1;
@@ -190,83 +183,6 @@ static int merge(const char *name, const char *path)
return ret;
}
-static void unlink_rr_item(const char *name)
-{
- unlink(rr_path(name, "thisimage"));
- unlink(rr_path(name, "preimage"));
- unlink(rr_path(name, "postimage"));
- rmdir(git_path("rr-cache/%s", name));
-}
-
-static void garbage_collect(struct path_list *rr)
-{
- struct path_list to_remove = { NULL, 0, 0, 1 };
- char buf[1024];
- DIR *dir;
- struct dirent *e;
- int len, i, cutoff;
- time_t now = time(NULL), then;
-
- strlcpy(buf, git_path("rr-cache"), sizeof(buf));
- len = strlen(buf);
- dir = opendir(buf);
- strcpy(buf + len++, "/");
- while ((e = readdir(dir))) {
- const char *name = e->d_name;
- struct stat st;
- if (name[0] == '.' && (name[1] == '\0' ||
- (name[1] == '.' && name[2] == '\0')))
- continue;
- i = snprintf(buf + len, sizeof(buf) - len, "%s", name);
- strlcpy(buf + len + i, "/preimage", sizeof(buf) - len - i);
- if (stat(buf, &st))
- continue;
- then = st.st_mtime;
- strlcpy(buf + len + i, "/postimage", sizeof(buf) - len - i);
- cutoff = stat(buf, &st) ? cutoff_noresolve : cutoff_resolve;
- if (then < now - cutoff * 86400) {
- buf[len + i] = '\0';
- path_list_insert(xstrdup(name), &to_remove);
- }
- }
- for (i = 0; i < to_remove.nr; i++)
- unlink_rr_item(to_remove.items[i].path);
- path_list_clear(&to_remove, 0);
-}
-
-static int outf(void *dummy, mmbuffer_t *ptr, int nbuf)
-{
- int i;
- for (i = 0; i < nbuf; i++)
- if (write_in_full(1, ptr[i].ptr, ptr[i].size) != ptr[i].size)
- return -1;
- return 0;
-}
-
-static int diff_two(const char *file1, const char *label1,
- const char *file2, const char *label2)
-{
- xpparam_t xpp;
- xdemitconf_t xecfg;
- xdemitcb_t ecb;
- mmfile_t minus, plus;
-
- if (read_mmfile(&minus, file1) || read_mmfile(&plus, file2))
- return 1;
-
- printf("--- a/%s\n+++ b/%s\n", label1, label2);
- fflush(stdout);
- xpp.flags = XDF_NEED_MINIMAL;
- memset(&xecfg, 0, sizeof(xecfg));
- xecfg.ctxlen = 3;
- ecb.outf = outf;
- xdi_diff(&minus, &plus, &xpp, &xecfg, &ecb);
-
- free(minus.ptr);
- free(plus.ptr);
- return 0;
-}
-
static int do_plain_rerere(struct path_list *rr, int fd)
{
struct path_list conflict = { NULL, 0, 0, 1 };
@@ -341,11 +257,7 @@ tail_optimization:
static int git_rerere_config(const char *var, const char *value, void *cb)
{
- if (!strcmp(var, "gc.rerereresolved"))
- cutoff_resolve = git_config_int(var, value);
- else if (!strcmp(var, "gc.rerereunresolved"))
- cutoff_noresolve = git_config_int(var, value);
- else if (!strcmp(var, "rerere.enabled"))
+ if (!strcmp(var, "rerere.enabled"))
rerere_enabled = git_config_bool(var, value);
else
return git_default_config(var, value, cb);
@@ -372,7 +284,7 @@ static int is_rerere_enabled(void)
return 1;
}
-static int setup_rerere(struct path_list *merge_rr)
+int setup_rerere(struct path_list *merge_rr)
{
int fd;
@@ -396,42 +308,3 @@ int rerere(void)
return 0;
return do_plain_rerere(&merge_rr, fd);
}
-
-int cmd_rerere(int argc, const char **argv, const char *prefix)
-{
- struct path_list merge_rr = { NULL, 0, 0, 1 };
- int i, fd;
-
- fd = setup_rerere(&merge_rr);
- if (fd < 0)
- return 0;
-
- if (argc < 2)
- return do_plain_rerere(&merge_rr, fd);
- else if (!strcmp(argv[1], "clear")) {
- for (i = 0; i < merge_rr.nr; i++) {
- struct stat st;
- const char *name = (const char *)merge_rr.items[i].util;
- if (!stat(git_path("rr-cache/%s", name), &st) &&
- S_ISDIR(st.st_mode) &&
- stat(rr_path(name, "postimage"), &st))
- unlink_rr_item(name);
- }
- unlink(merge_rr_path);
- } else if (!strcmp(argv[1], "gc"))
- garbage_collect(&merge_rr);
- else if (!strcmp(argv[1], "status"))
- for (i = 0; i < merge_rr.nr; i++)
- printf("%s\n", merge_rr.items[i].path);
- else if (!strcmp(argv[1], "diff"))
- for (i = 0; i < merge_rr.nr; i++) {
- const char *path = merge_rr.items[i].path;
- const char *name = (const char *)merge_rr.items[i].util;
- diff_two(rr_path(name, "preimage"), path, path, path);
- }
- else
- usage(git_rerere_usage);
-
- path_list_clear(&merge_rr, 1);
- return 0;
-}
diff --git a/rerere.h b/rerere.h
new file mode 100644
index 0000000..35b0fa8
--- /dev/null
+++ b/rerere.h
@@ -0,0 +1,9 @@
+#ifndef RERERE_H
+#define RERERE_H
+
+#include "path-list.h"
+
+extern int setup_rerere(struct path_list *);
+extern int rerere(void);
+
+#endif
--
1.5.6.2.574.gd4568
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH] rerere: Separate libgit and builtin functions
2008-07-09 10:18 ` [PATCH] rerere: Separate libgit and builtin functions Stephan Beyer
@ 2008-07-09 11:55 ` Johannes Schindelin
2008-07-09 12:00 ` Stephan Beyer
2008-07-09 12:03 ` [PATCH] " Johannes Schindelin
1 sibling, 1 reply; 11+ messages in thread
From: Johannes Schindelin @ 2008-07-09 11:55 UTC (permalink / raw)
To: Stephan Beyer; +Cc: git, Junio C Hamano
Hi,
On Wed, 9 Jul 2008, Stephan Beyer wrote:
> This patch moves rerere()-related functions into a newly created
> rerere.c file. Also setup_rerere() is moved into rerere.c to decrease
> code duplications for rerere.c and builtin-rerere.c.
It is not moved to decrease code duplication, but because it is needed by
rerere().
Ciao,
Dscho
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] rerere: Separate libgit and builtin functions
2008-07-09 11:55 ` Johannes Schindelin
@ 2008-07-09 12:00 ` Stephan Beyer
2008-07-09 12:58 ` [PATCHv2] " Stephan Beyer
0 siblings, 1 reply; 11+ messages in thread
From: Stephan Beyer @ 2008-07-09 12:00 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git, Junio C Hamano
> > This patch moves rerere()-related functions into a newly created
> > rerere.c file. Also setup_rerere() is moved into rerere.c to decrease
> > code duplications for rerere.c and builtin-rerere.c.
>
> It is not moved to decrease code duplication, but because it is needed by
> rerere().
Right.
And btw the patch seems to be broken. (At least I can't apply it
here...) Sorry :( Usually I test applying before sending but this time
lunch was eliciting.
Well, I'm going to fix that.
--
Stephan Beyer <s-beyer@gmx.net>, PGP 0x6EDDD207FCC5040F
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] rerere: Separate libgit and builtin functions
2008-07-09 10:18 ` [PATCH] rerere: Separate libgit and builtin functions Stephan Beyer
2008-07-09 11:55 ` Johannes Schindelin
@ 2008-07-09 12:03 ` Johannes Schindelin
2008-07-09 18:25 ` Junio C Hamano
1 sibling, 1 reply; 11+ messages in thread
From: Johannes Schindelin @ 2008-07-09 12:03 UTC (permalink / raw)
To: Stephan Beyer; +Cc: git, Junio C Hamano
Hi,
On Wed, 9 Jul 2008, Stephan Beyer wrote:
> Makefile | 2 +
> builtin-rerere.c | 324 +++---------------------------------------
> builtin-rerere.c => rerere.c | 133 +-----------------
> rerere.h | 9 ++
> 4 files changed, 32 insertions(+), 436 deletions(-)
Heh, that sounds nice! Deleting way more lines than adding! :-)
> copy builtin-rerere.c => rerere.c (66%)
Oh, well :-)
> diff --git a/builtin-rerere.c b/rerere.c
> similarity index 66%
> copy from builtin-rerere.c
> copy to rerere.c
> index 85222d9..5c22bed 100644
> --- a/builtin-rerere.c
> +++ b/rerere.c
> @@ -1,18 +1,11 @@
> -#include "builtin.h"
> #include "cache.h"
> #include "path-list.h"
> +#include "rerere.h"
> #include "xdiff/xdiff.h"
> #include "xdiff-interface.h"
>
> #include <time.h>
No longer necessary, is it?
> diff --git a/rerere.h b/rerere.h
> new file mode 100644
> index 0000000..35b0fa8
> --- /dev/null
> +++ b/rerere.h
> @@ -0,0 +1,9 @@
> +#ifndef RERERE_H
> +#define RERERE_H
> +
> +#include "path-list.h"
> +
> +extern int setup_rerere(struct path_list *);
Why?
Ah, it is needed for "gc". Maybe this needs documentation, since it cause
some minutes of head scratching with yours truly.
Ciao,
Dscho
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCHv2] rerere: Separate libgit and builtin functions
2008-07-09 12:00 ` Stephan Beyer
@ 2008-07-09 12:58 ` Stephan Beyer
0 siblings, 0 replies; 11+ messages in thread
From: Stephan Beyer @ 2008-07-09 12:58 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Junio C Hamano, git, Stephan Beyer
This patch moves rerere()-related functions into a newly created
rerere.c file.
The setup_rerere() function is needed by both rerere() and cmd_rerere(),
so this function is moved to rerere.c and declared non-static (and "extern")
in newly created rerere.h file.
Signed-off-by: Stephan Beyer <s-beyer@gmx.net>
---
Hi again,
so now it should apply cleanly.
Seems that I had not built the topic branch of the former patch
on top of the latest master by accident.
Regards,
Stephan
Makefile | 2 +
builtin-commit.c | 1 +
builtin-rerere.c | 362 ++---------------------------------------
commit.h | 1 -
builtin-rerere.c => rerere.c | 129 +---------------
rerere.h | 9 +
6 files changed, 33 insertions(+), 471 deletions(-)
copy builtin-rerere.c => rerere.c (71%)
create mode 100644 rerere.h
diff --git a/Makefile b/Makefile
index 4796565..de15163 100644
--- a/Makefile
+++ b/Makefile
@@ -363,6 +363,7 @@ LIB_H += quote.h
LIB_H += reflog-walk.h
LIB_H += refs.h
LIB_H += remote.h
+LIB_H += rerere.h
LIB_H += revision.h
LIB_H += run-command.h
LIB_H += sha1-lookup.h
@@ -447,6 +448,7 @@ LIB_OBJS += read-cache.o
LIB_OBJS += reflog-walk.o
LIB_OBJS += refs.o
LIB_OBJS += remote.o
+LIB_OBJS += rerere.o
LIB_OBJS += revision.o
LIB_OBJS += run-command.o
LIB_OBJS += server-info.o
diff --git a/builtin-commit.c b/builtin-commit.c
index 745c11e..bdc83df 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -22,6 +22,7 @@
#include "utf8.h"
#include "parse-options.h"
#include "path-list.h"
+#include "rerere.h"
#include "unpack-trees.h"
static const char * const builtin_commit_usage[] = {
diff --git a/builtin-rerere.c b/builtin-rerere.c
index 839b26e..5d40e16 100644
--- a/builtin-rerere.c
+++ b/builtin-rerere.c
@@ -1,11 +1,10 @@
#include "builtin.h"
#include "cache.h"
#include "path-list.h"
+#include "rerere.h"
#include "xdiff/xdiff.h"
#include "xdiff-interface.h"
-#include <time.h>
-
static const char git_rerere_usage[] =
"git-rerere [clear | status | diff | gc]";
@@ -13,14 +12,6 @@ static const char git_rerere_usage[] =
static int cutoff_noresolve = 15;
static int cutoff_resolve = 60;
-/* if rerere_enabled == -1, fall back to detection of .git/rr-cache */
-static int rerere_enabled = -1;
-
-/* automatically update cleanly resolved paths to the index */
-static int rerere_autoupdate;
-
-static char *merge_rr_path;
-
static const char *rr_path(const char *name, const char *file)
{
return git_path("rr-cache/%s/%s", name, file);
@@ -38,179 +29,6 @@ static int has_resolution(const char *name)
return !stat(rr_path(name, "postimage"), &st);
}
-static void read_rr(struct path_list *rr)
-{
- unsigned char sha1[20];
- char buf[PATH_MAX];
- FILE *in = fopen(merge_rr_path, "r");
- if (!in)
- return;
- while (fread(buf, 40, 1, in) == 1) {
- int i;
- char *name;
- if (get_sha1_hex(buf, sha1))
- die("corrupt MERGE_RR");
- buf[40] = '\0';
- name = xstrdup(buf);
- if (fgetc(in) != '\t')
- die("corrupt MERGE_RR");
- for (i = 0; i < sizeof(buf) && (buf[i] = fgetc(in)); i++)
- ; /* do nothing */
- if (i == sizeof(buf))
- die("filename too long");
- path_list_insert(buf, rr)->util = name;
- }
- fclose(in);
-}
-
-static struct lock_file write_lock;
-
-static int write_rr(struct path_list *rr, int out_fd)
-{
- int i;
- for (i = 0; i < rr->nr; i++) {
- const char *path;
- int length;
- if (!rr->items[i].util)
- continue;
- path = rr->items[i].path;
- length = strlen(path) + 1;
- if (write_in_full(out_fd, rr->items[i].util, 40) != 40 ||
- write_in_full(out_fd, "\t", 1) != 1 ||
- write_in_full(out_fd, path, length) != length)
- die("unable to write rerere record");
- }
- if (commit_lock_file(&write_lock) != 0)
- die("unable to write rerere record");
- return 0;
-}
-
-static int handle_file(const char *path,
- unsigned char *sha1, const char *output)
-{
- SHA_CTX ctx;
- char buf[1024];
- int hunk = 0, hunk_no = 0;
- struct strbuf one, two;
- FILE *f = fopen(path, "r");
- FILE *out = NULL;
-
- if (!f)
- return error("Could not open %s", path);
-
- if (output) {
- out = fopen(output, "w");
- if (!out) {
- fclose(f);
- return error("Could not write %s", output);
- }
- }
-
- if (sha1)
- SHA1_Init(&ctx);
-
- strbuf_init(&one, 0);
- strbuf_init(&two, 0);
- while (fgets(buf, sizeof(buf), f)) {
- if (!prefixcmp(buf, "<<<<<<< "))
- hunk = 1;
- else if (!prefixcmp(buf, "======="))
- hunk = 2;
- else if (!prefixcmp(buf, ">>>>>>> ")) {
- if (strbuf_cmp(&one, &two) > 0)
- strbuf_swap(&one, &two);
- hunk_no++;
- hunk = 0;
- if (out) {
- fputs("<<<<<<<\n", out);
- fwrite(one.buf, one.len, 1, out);
- fputs("=======\n", out);
- fwrite(two.buf, two.len, 1, out);
- fputs(">>>>>>>\n", out);
- }
- if (sha1) {
- SHA1_Update(&ctx, one.buf ? one.buf : "",
- one.len + 1);
- SHA1_Update(&ctx, two.buf ? two.buf : "",
- two.len + 1);
- }
- strbuf_reset(&one);
- strbuf_reset(&two);
- } else if (hunk == 1)
- strbuf_addstr(&one, buf);
- else if (hunk == 2)
- strbuf_addstr(&two, buf);
- else if (out)
- fputs(buf, out);
- }
- strbuf_release(&one);
- strbuf_release(&two);
-
- fclose(f);
- if (out)
- fclose(out);
- if (sha1)
- SHA1_Final(sha1, &ctx);
- if (hunk) {
- if (output)
- unlink(output);
- return error("Could not parse conflict hunks in %s", path);
- }
- return hunk_no;
-}
-
-static int find_conflict(struct path_list *conflict)
-{
- int i;
- if (read_cache() < 0)
- return error("Could not read index");
- for (i = 0; i+1 < active_nr; i++) {
- struct cache_entry *e2 = active_cache[i];
- struct cache_entry *e3 = active_cache[i+1];
- if (ce_stage(e2) == 2 &&
- ce_stage(e3) == 3 &&
- ce_same_name(e2, e3) &&
- S_ISREG(e2->ce_mode) &&
- S_ISREG(e3->ce_mode)) {
- path_list_insert((const char *)e2->name, conflict);
- i++; /* skip over both #2 and #3 */
- }
- }
- return 0;
-}
-
-static int merge(const char *name, const char *path)
-{
- int ret;
- mmfile_t cur, base, other;
- mmbuffer_t result = {NULL, 0};
- xpparam_t xpp = {XDF_NEED_MINIMAL};
-
- if (handle_file(path, NULL, rr_path(name, "thisimage")) < 0)
- return 1;
-
- if (read_mmfile(&cur, rr_path(name, "thisimage")) ||
- read_mmfile(&base, rr_path(name, "preimage")) ||
- read_mmfile(&other, rr_path(name, "postimage")))
- return 1;
- ret = xdl_merge(&base, &cur, "", &other, "",
- &xpp, XDL_MERGE_ZEALOUS, &result);
- if (!ret) {
- FILE *f = fopen(path, "w");
- if (!f)
- return error("Could not write to %s", path);
- fwrite(result.ptr, result.size, 1, f);
- fclose(f);
- }
-
- free(cur.ptr);
- free(base.ptr);
- free(other.ptr);
- free(result.ptr);
-
- return ret;
-}
-
static void unlink_rr_item(const char *name)
{
unlink(rr_path(name, "thisimage"));
@@ -219,6 +37,17 @@ static void unlink_rr_item(const char *name)
rmdir(git_path("rr-cache/%s", name));
}
+static int git_rerere_gc_config(const char *var, const char *value, void *cb)
+{
+ if (!strcmp(var, "gc.rerereresolved"))
+ cutoff_resolve = git_config_int(var, value);
+ else if (!strcmp(var, "gc.rerereunresolved"))
+ cutoff_noresolve = git_config_int(var, value);
+ else
+ return git_default_config(var, value, cb);
+ return 0;
+}
+
static void garbage_collect(struct path_list *rr)
{
struct path_list to_remove = { NULL, 0, 0, 1 };
@@ -227,6 +56,7 @@ static void garbage_collect(struct path_list *rr)
int i, cutoff;
time_t now = time(NULL), then;
+ git_config(git_rerere_gc_config, NULL);
dir = opendir(git_path("rr-cache"));
while ((e = readdir(dir))) {
const char *name = e->d_name;
@@ -279,181 +109,25 @@ static int diff_two(const char *file1, const char *label1,
return 0;
}
-static struct lock_file index_lock;
-
-static int update_paths(struct path_list *update)
-{
- int i;
- int fd = hold_locked_index(&index_lock, 0);
- int status = 0;
-
- if (fd < 0)
- return -1;
-
- for (i = 0; i < update->nr; i++) {
- struct path_list_item *item = &update->items[i];
- if (add_file_to_cache(item->path, ADD_CACHE_IGNORE_ERRORS))
- status = -1;
- }
-
- if (!status && active_cache_changed) {
- if (write_cache(fd, active_cache, active_nr) ||
- commit_locked_index(&index_lock))
- die("Unable to write new index file");
- } else if (fd >= 0)
- rollback_lock_file(&index_lock);
- return status;
-}
-
-static int do_plain_rerere(struct path_list *rr, int fd)
-{
- struct path_list conflict = { NULL, 0, 0, 1 };
- struct path_list update = { NULL, 0, 0, 1 };
- int i;
-
- find_conflict(&conflict);
-
- /*
- * MERGE_RR records paths with conflicts immediately after merge
- * failed. Some of the conflicted paths might have been hand resolved
- * in the working tree since then, but the initial run would catch all
- * and register their preimages.
- */
-
- for (i = 0; i < conflict.nr; i++) {
- const char *path = conflict.items[i].path;
- if (!path_list_has_path(rr, path)) {
- unsigned char sha1[20];
- char *hex;
- int ret;
- ret = handle_file(path, sha1, NULL);
- if (ret < 1)
- continue;
- hex = xstrdup(sha1_to_hex(sha1));
- path_list_insert(path, rr)->util = hex;
- if (mkdir(git_path("rr-cache/%s", hex), 0755))
- continue;;
- handle_file(path, NULL, rr_path(hex, "preimage"));
- fprintf(stderr, "Recorded preimage for '%s'\n", path);
- }
- }
-
- /*
- * Now some of the paths that had conflicts earlier might have been
- * hand resolved. Others may be similar to a conflict already that
- * was resolved before.
- */
-
- for (i = 0; i < rr->nr; i++) {
- int ret;
- const char *path = rr->items[i].path;
- const char *name = (const char *)rr->items[i].util;
-
- if (has_resolution(name)) {
- if (!merge(name, path)) {
- fprintf(stderr, "Resolved '%s' using "
- "previous resolution.\n", path);
- if (rerere_autoupdate)
- path_list_insert(path, &update);
- goto mark_resolved;
- }
- }
-
- /* Let's see if we have resolved it. */
- ret = handle_file(path, NULL, NULL);
- if (ret)
- continue;
-
- fprintf(stderr, "Recorded resolution for '%s'.\n", path);
- copy_file(rr_path(name, "postimage"), path, 0666);
- mark_resolved:
- rr->items[i].util = NULL;
- }
-
- if (update.nr)
- update_paths(&update);
-
- return write_rr(rr, fd);
-}
-
-static int git_rerere_config(const char *var, const char *value, void *cb)
-{
- if (!strcmp(var, "gc.rerereresolved"))
- cutoff_resolve = git_config_int(var, value);
- else if (!strcmp(var, "gc.rerereunresolved"))
- cutoff_noresolve = git_config_int(var, value);
- else if (!strcmp(var, "rerere.enabled"))
- rerere_enabled = git_config_bool(var, value);
- else if (!strcmp(var, "rerere.autoupdate"))
- rerere_autoupdate = git_config_bool(var, value);
- else
- return git_default_config(var, value, cb);
- return 0;
-}
-
-static int is_rerere_enabled(void)
-{
- struct stat st;
- const char *rr_cache;
- int rr_cache_exists;
-
- if (!rerere_enabled)
- return 0;
-
- rr_cache = git_path("rr-cache");
- rr_cache_exists = !stat(rr_cache, &st) && S_ISDIR(st.st_mode);
- if (rerere_enabled < 0)
- return rr_cache_exists;
-
- if (!rr_cache_exists &&
- (mkdir(rr_cache, 0777) || adjust_shared_perm(rr_cache)))
- die("Could not create directory %s", rr_cache);
- return 1;
-}
-
-static int setup_rerere(struct path_list *merge_rr)
-{
- int fd;
-
- git_config(git_rerere_config, NULL);
- if (!is_rerere_enabled())
- return -1;
-
- merge_rr_path = xstrdup(git_path("rr-cache/MERGE_RR"));
- fd = hold_lock_file_for_update(&write_lock, merge_rr_path, 1);
- read_rr(merge_rr);
- return fd;
-}
-
-int rerere(void)
-{
- struct path_list merge_rr = { NULL, 0, 0, 1 };
- int fd;
-
- fd = setup_rerere(&merge_rr);
- if (fd < 0)
- return 0;
- return do_plain_rerere(&merge_rr, fd);
-}
-
int cmd_rerere(int argc, const char **argv, const char *prefix)
{
struct path_list merge_rr = { NULL, 0, 0, 1 };
int i, fd;
+ if (argc < 2)
+ return rerere();
+
fd = setup_rerere(&merge_rr);
if (fd < 0)
return 0;
- if (argc < 2)
- return do_plain_rerere(&merge_rr, fd);
- else if (!strcmp(argv[1], "clear")) {
+ if (!strcmp(argv[1], "clear")) {
for (i = 0; i < merge_rr.nr; i++) {
const char *name = (const char *)merge_rr.items[i].util;
if (!has_resolution(name))
unlink_rr_item(name);
}
- unlink(merge_rr_path);
+ unlink(git_path("rr-cache/MERGE_RR"));
} else if (!strcmp(argv[1], "gc"))
garbage_collect(&merge_rr);
else if (!strcmp(argv[1], "status"))
diff --git a/commit.h b/commit.h
index 2d94d41..fda7ad0 100644
--- a/commit.h
+++ b/commit.h
@@ -131,7 +131,6 @@ extern struct commit_list *get_shallow_commits(struct object_array *heads,
int in_merge_bases(struct commit *, struct commit **, int);
extern int interactive_add(int argc, const char **argv, const char *prefix);
-extern int rerere(void);
static inline int single_parent(struct commit *commit)
{
diff --git a/builtin-rerere.c b/rerere.c
similarity index 71%
copy from builtin-rerere.c
copy to rerere.c
index 839b26e..bbd8c00 100644
--- a/builtin-rerere.c
+++ b/rerere.c
@@ -1,18 +1,9 @@
-#include "builtin.h"
#include "cache.h"
#include "path-list.h"
+#include "rerere.h"
#include "xdiff/xdiff.h"
#include "xdiff-interface.h"
-#include <time.h>
-
-static const char git_rerere_usage[] =
-"git-rerere [clear | status | diff | gc]";
-
-/* these values are days */
-static int cutoff_noresolve = 15;
-static int cutoff_resolve = 60;
-
/* if rerere_enabled == -1, fall back to detection of .git/rr-cache */
static int rerere_enabled = -1;
@@ -26,12 +17,6 @@ static const char *rr_path(const char *name, const char *file)
return git_path("rr-cache/%s/%s", name, file);
}
-static time_t rerere_created_at(const char *name)
-{
- struct stat st;
- return stat(rr_path(name, "preimage"), &st) ? (time_t) 0 : st.st_mtime;
-}
-
static int has_resolution(const char *name)
{
struct stat st;
@@ -211,74 +196,6 @@ static int merge(const char *name, const char *path)
return ret;
}
-static void unlink_rr_item(const char *name)
-{
- unlink(rr_path(name, "thisimage"));
- unlink(rr_path(name, "preimage"));
- unlink(rr_path(name, "postimage"));
- rmdir(git_path("rr-cache/%s", name));
-}
-
-static void garbage_collect(struct path_list *rr)
-{
- struct path_list to_remove = { NULL, 0, 0, 1 };
- DIR *dir;
- struct dirent *e;
- int i, cutoff;
- time_t now = time(NULL), then;
-
- dir = opendir(git_path("rr-cache"));
- while ((e = readdir(dir))) {
- const char *name = e->d_name;
- if (name[0] == '.' &&
- (name[1] == '\0' || (name[1] == '.' && name[2] == '\0')))
- continue;
- then = rerere_created_at(name);
- if (!then)
- continue;
- cutoff = (has_resolution(name)
- ? cutoff_resolve : cutoff_noresolve);
- if (then < now - cutoff * 86400)
- path_list_append(name, &to_remove);
- }
- for (i = 0; i < to_remove.nr; i++)
- unlink_rr_item(to_remove.items[i].path);
- path_list_clear(&to_remove, 0);
-}
-
-static int outf(void *dummy, mmbuffer_t *ptr, int nbuf)
-{
- int i;
- for (i = 0; i < nbuf; i++)
- if (write_in_full(1, ptr[i].ptr, ptr[i].size) != ptr[i].size)
- return -1;
- return 0;
-}
-
-static int diff_two(const char *file1, const char *label1,
- const char *file2, const char *label2)
-{
- xpparam_t xpp;
- xdemitconf_t xecfg;
- xdemitcb_t ecb;
- mmfile_t minus, plus;
-
- if (read_mmfile(&minus, file1) || read_mmfile(&plus, file2))
- return 1;
-
- printf("--- a/%s\n+++ b/%s\n", label1, label2);
- fflush(stdout);
- xpp.flags = XDF_NEED_MINIMAL;
- memset(&xecfg, 0, sizeof(xecfg));
- xecfg.ctxlen = 3;
- ecb.outf = outf;
- xdi_diff(&minus, &plus, &xpp, &xecfg, &ecb);
-
- free(minus.ptr);
- free(plus.ptr);
- return 0;
-}
-
static struct lock_file index_lock;
static int update_paths(struct path_list *update)
@@ -378,11 +295,7 @@ static int do_plain_rerere(struct path_list *rr, int fd)
static int git_rerere_config(const char *var, const char *value, void *cb)
{
- if (!strcmp(var, "gc.rerereresolved"))
- cutoff_resolve = git_config_int(var, value);
- else if (!strcmp(var, "gc.rerereunresolved"))
- cutoff_noresolve = git_config_int(var, value);
- else if (!strcmp(var, "rerere.enabled"))
+ if (!strcmp(var, "rerere.enabled"))
rerere_enabled = git_config_bool(var, value);
else if (!strcmp(var, "rerere.autoupdate"))
rerere_autoupdate = git_config_bool(var, value);
@@ -411,7 +324,7 @@ static int is_rerere_enabled(void)
return 1;
}
-static int setup_rerere(struct path_list *merge_rr)
+int setup_rerere(struct path_list *merge_rr)
{
int fd;
@@ -435,39 +348,3 @@ int rerere(void)
return 0;
return do_plain_rerere(&merge_rr, fd);
}
-
-int cmd_rerere(int argc, const char **argv, const char *prefix)
-{
- struct path_list merge_rr = { NULL, 0, 0, 1 };
- int i, fd;
-
- fd = setup_rerere(&merge_rr);
- if (fd < 0)
- return 0;
-
- if (argc < 2)
- return do_plain_rerere(&merge_rr, fd);
- else if (!strcmp(argv[1], "clear")) {
- for (i = 0; i < merge_rr.nr; i++) {
- const char *name = (const char *)merge_rr.items[i].util;
- if (!has_resolution(name))
- unlink_rr_item(name);
- }
- unlink(merge_rr_path);
- } else if (!strcmp(argv[1], "gc"))
- garbage_collect(&merge_rr);
- else if (!strcmp(argv[1], "status"))
- for (i = 0; i < merge_rr.nr; i++)
- printf("%s\n", merge_rr.items[i].path);
- else if (!strcmp(argv[1], "diff"))
- for (i = 0; i < merge_rr.nr; i++) {
- const char *path = merge_rr.items[i].path;
- const char *name = (const char *)merge_rr.items[i].util;
- diff_two(rr_path(name, "preimage"), path, path, path);
- }
- else
- usage(git_rerere_usage);
-
- path_list_clear(&merge_rr, 1);
- return 0;
-}
diff --git a/rerere.h b/rerere.h
new file mode 100644
index 0000000..35b0fa8
--- /dev/null
+++ b/rerere.h
@@ -0,0 +1,9 @@
+#ifndef RERERE_H
+#define RERERE_H
+
+#include "path-list.h"
+
+extern int setup_rerere(struct path_list *);
+extern int rerere(void);
+
+#endif
--
1.5.6
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH] rerere: Separate libgit and builtin functions
2008-07-09 12:03 ` [PATCH] " Johannes Schindelin
@ 2008-07-09 18:25 ` Junio C Hamano
0 siblings, 0 replies; 11+ messages in thread
From: Junio C Hamano @ 2008-07-09 18:25 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Stephan Beyer, git
Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> On Wed, 9 Jul 2008, Stephan Beyer wrote:
>
>> Makefile | 2 +
>> builtin-rerere.c | 324 +++---------------------------------------
>> builtin-rerere.c => rerere.c | 133 +-----------------
>> rerere.h | 9 ++
>> 4 files changed, 32 insertions(+), 436 deletions(-)
>
> Heh, that sounds nice! Deleting way more lines than adding! :-)
>
>> copy builtin-rerere.c => rerere.c (66%)
>
> Oh, well :-)
We may want to fix this, though. I haven't verified by looking at the
diffstat summary code, but what I think is happening is that the bogus 436
is the result of counting the lines removed from builtin-rerere.c (that
lost many of its lines to rerere.c), and also counting the lines that were
remove from rerere.c pretending as if rerere.c had full contents of
builtin-rerere.c initially (i.e., counting the lines that were _not_ moved
to rerere.c).
It may just be the matter of subtracting the size of the preimage of
copied files (in this case, builtin-rerere.c that was used to initialize
rerere.c) from the grand total of deleted lines. I dunno.
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2008-07-09 18:26 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-07-09 0:17 [PATCH] git-rerere.txt: Mention rr-cache directory Stephan Beyer
2008-07-09 0:25 ` Johannes Schindelin
2008-07-09 0:38 ` Johannes Schindelin
2008-07-09 1:09 ` Junio C Hamano
2008-07-09 9:21 ` Stephan Beyer
2008-07-09 10:18 ` [PATCH] rerere: Separate libgit and builtin functions Stephan Beyer
2008-07-09 11:55 ` Johannes Schindelin
2008-07-09 12:00 ` Stephan Beyer
2008-07-09 12:58 ` [PATCHv2] " Stephan Beyer
2008-07-09 12:03 ` [PATCH] " Johannes Schindelin
2008-07-09 18:25 ` Junio C Hamano
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).