* [PATCH v2 3/9] sequencer: let "git sequencer--helper" callers set "allow_dirty"
From: Christian Couder @ 2009-08-21 5:49 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Johannes Schindelin, Stephan Beyer, Daniel Barkalow,
Jakub Narebski
In-Reply-To: <20090821054729.3726.5078.chriscool@tuxfamily.org>
This flag can be set when using --reset-hard or --fast-forward, and
in this case changes in the work tree will be kept.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
builtin-sequencer--helper.c | 11 ++++++++---
1 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/builtin-sequencer--helper.c b/builtin-sequencer--helper.c
index bd72f65..71a7fef 100644
--- a/builtin-sequencer--helper.c
+++ b/builtin-sequencer--helper.c
@@ -18,8 +18,10 @@ static unsigned char head_sha1[20];
static const char * const git_sequencer_helper_usage[] = {
"git sequencer--helper --make-patch <commit>",
- "git sequencer--helper --reset-hard <commit> <reflog-msg> <verbosity>",
- "git sequencer--helper --fast-forward <commit> <reflog-msg> <verbosity>",
+ "git sequencer--helper --reset-hard <commit> <reflog-msg> "
+ "<verbosity> [<allow-dirty>]",
+ "git sequencer--helper --fast-forward <commit> <reflog-msg> "
+ "<verbosity> [<allow-dirty>]",
NULL
};
@@ -247,7 +249,7 @@ int cmd_sequencer__helper(int argc, const char **argv, const char *prefix)
unsigned char sha1[20];
char *commit = ff_commit ? ff_commit : reset_commit;
- if (argc != 2)
+ if (argc != 2 && argc != 3)
usage_with_options(git_sequencer_helper_usage,
options);
@@ -263,6 +265,9 @@ int cmd_sequencer__helper(int argc, const char **argv, const char *prefix)
return 1;
}
+ if (argc == 3 && *argv[2] && strcmp(argv[2], "0"))
+ allow_dirty = 1;
+
if (ff_commit)
return do_fast_forward(sha1);
else
--
1.6.4.271.ge010d
^ permalink raw reply related
* [PATCH v2 8/9] sequencer: add "--cherry-pick" option to "git sequencer--helper"
From: Christian Couder @ 2009-08-21 5:49 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Johannes Schindelin, Stephan Beyer, Daniel Barkalow,
Jakub Narebski
In-Reply-To: <20090821054729.3726.5078.chriscool@tuxfamily.org>
From: Stephan Beyer <s-beyer@gmx.net>
This patch adds some code that comes from the sequencer GSoC project:
git://repo.or.cz/git/sbeyer.git
(commit 5a78908b70ceb5a4ea9fd4b82f07ceba1f019079)
Most of the code from do_cherry_pick() is taken from the
sequencer insn_pick_act() function.
Mentored-by: Daniel Barkalow <barkalow@iabervon.org>
Mentored-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Stephan Beyer <s-beyer@gmx.net>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
builtin-sequencer--helper.c | 71 +++++++++++++++++++++++++++++++++++++------
1 files changed, 61 insertions(+), 10 deletions(-)
diff --git a/builtin-sequencer--helper.c b/builtin-sequencer--helper.c
index 61a8f2e..291ba18 100644
--- a/builtin-sequencer--helper.c
+++ b/builtin-sequencer--helper.c
@@ -60,7 +60,8 @@ static const char * const git_sequencer_helper_usage[] = {
"<verbosity> [<allow-dirty>]",
"git sequencer--helper --fast-forward <commit> <reflog-msg> "
"<verbosity> [<allow-dirty>]",
- "git sequencer--helper --cherry-pick <commit> [<do-not-commit>]",
+ "git sequencer--helper --cherry-pick <commit> <reflog-msg> "
+ "<verbosity> [<do-not-commit>]",
NULL
};
@@ -288,7 +289,7 @@ static int do_commit(unsigned char *parent_sha1)
if (update_ref(reflog, "HEAD", commit_sha1, NULL, 0, 0))
return error("Could not update HEAD to %s.",
- sha1_to_hex(commit_sha1));
+ sha1_to_hex(commit_sha1));
return 0;
}
@@ -408,6 +409,46 @@ static int write_commit_summary_into(const char *filename)
return 0;
}
+static int do_cherry_pick(char *cp_commit, int no_commit)
+{
+ struct commit *commit;
+ int failed;
+ const char *author;
+
+ if (get_sha1("HEAD", head_sha1))
+ return error("You do not have a valid HEAD.");
+
+ commit = get_commit(cp_commit);
+ if (!commit)
+ return 1;
+
+ set_pick_subject(cp_commit, commit);
+
+ failed = pick_commit(commit, 0, 0, &next_commit.summary);
+
+ set_message_source(sha1_to_hex(commit->object.sha1));
+ author = strstr(commit->buffer, "\nauthor ");
+ if (author)
+ set_author_info(author + 8);
+
+ /* We do not want extra Conflicts: lines on cherry-pick,
+ so just take the old commit message. */
+ if (failed) {
+ strbuf_setlen(&next_commit.summary, 0);
+ strbuf_addstr(&next_commit.summary,
+ strstr(commit->buffer, "\n\n") + 2);
+ rerere();
+ make_patch(commit);
+ write_commit_summary_into(MERGE_MSG);
+ return error(pick_help_msg(commit->object.sha1, 0));
+ }
+
+ if (!no_commit && do_commit(head_sha1))
+ return error("Could not commit.");
+
+ return 0;
+}
+
/**********************************************************************
* Builtin sequencer helper functions
*/
@@ -436,6 +477,7 @@ int cmd_sequencer__helper(int argc, const char **argv, const char *prefix)
char *patch_commit = NULL;
char *reset_commit = NULL;
char *ff_commit = NULL;
+ char *cp_commit = NULL;
struct option options[] = {
OPT_STRING(0, "make-patch", &patch_commit, "commit",
"create a patch from commit"),
@@ -443,6 +485,8 @@ int cmd_sequencer__helper(int argc, const char **argv, const char *prefix)
"reset to commit"),
OPT_STRING(0, "fast-forward", &ff_commit, "commit",
"fast forward to commit"),
+ OPT_STRING(0, "cherry-pick", &cp_commit, "commit",
+ "cherry pick commit"),
OPT_END()
};
@@ -459,19 +503,15 @@ int cmd_sequencer__helper(int argc, const char **argv, const char *prefix)
return 0;
}
- if (ff_commit || reset_commit) {
+ if (cp_commit || ff_commit || reset_commit) {
unsigned char sha1[20];
- char *commit = ff_commit ? ff_commit : reset_commit;
+ char *commit;
+ int opt_arg = 0;
if (argc != 2 && argc != 3)
usage_with_options(git_sequencer_helper_usage,
options);
- if (get_sha1(commit, sha1)) {
- error("Could not find '%s'", commit);
- return 1;
- }
-
reflog = (char *)argv[0];
if (parse_verbosity(argv[1])) {
@@ -480,7 +520,18 @@ int cmd_sequencer__helper(int argc, const char **argv, const char *prefix)
}
if (argc == 3 && *argv[2] && strcmp(argv[2], "0"))
- allow_dirty = 1;
+ opt_arg = 1;
+
+ if (cp_commit)
+ return do_cherry_pick(cp_commit, opt_arg);
+
+ allow_dirty = opt_arg;
+
+ commit = ff_commit ? ff_commit : reset_commit;
+ if (get_sha1(commit, sha1)) {
+ error("Could not find '%s'", commit);
+ return 1;
+ }
if (ff_commit)
return do_fast_forward(sha1);
--
1.6.4.271.ge010d
^ permalink raw reply related
* [PATCH v2 5/9] revert: libify pick
From: Christian Couder @ 2009-08-21 5:49 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Johannes Schindelin, Stephan Beyer, Daniel Barkalow,
Jakub Narebski
In-Reply-To: <20090821054729.3726.5078.chriscool@tuxfamily.org>
From: Stephan Beyer <s-beyer@gmx.net>
This commit is made of code from the sequencer GSoC project:
git://repo.or.cz/git/sbeyer.git
(commit 5a78908b70ceb5a4ea9fd4b82f07ceba1f019079)
The goal of this commit is to abstract out pick functionnality
into a new pick() function made of code from "builtin-revert.c".
The new pick() function is in a new "pick.c" file with an
associated "pick.h".
This commit contains some changes suggested by Junio.
Mentored-by: Daniel Barkalow <barkalow@iabervon.org>
Mentored-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Stephan Beyer <s-beyer@gmx.net>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
Makefile | 2 +
builtin-revert.c | 272 +++++++++---------------------------------------------
pick.c | 210 +++++++++++++++++++++++++++++++++++++++++
pick.h | 13 +++
4 files changed, 269 insertions(+), 228 deletions(-)
create mode 100644 pick.c
create mode 100644 pick.h
diff --git a/Makefile b/Makefile
index 98dd01d..5e76083 100644
--- a/Makefile
+++ b/Makefile
@@ -445,6 +445,7 @@ LIB_H += pack-refs.h
LIB_H += pack-revindex.h
LIB_H += parse-options.h
LIB_H += patch-ids.h
+LIB_H += pick.h
LIB_H += pkt-line.h
LIB_H += progress.h
LIB_H += quote.h
@@ -533,6 +534,7 @@ LIB_OBJS += parse-options.o
LIB_OBJS += patch-delta.o
LIB_OBJS += patch-ids.o
LIB_OBJS += path.o
+LIB_OBJS += pick.o
LIB_OBJS += pkt-line.o
LIB_OBJS += preload-index.o
LIB_OBJS += pretty.o
diff --git a/builtin-revert.c b/builtin-revert.c
index 151aa6a..4797ac5 100644
--- a/builtin-revert.c
+++ b/builtin-revert.c
@@ -1,18 +1,14 @@
#include "cache.h"
#include "builtin.h"
-#include "object.h"
#include "commit.h"
#include "tag.h"
-#include "wt-status.h"
-#include "run-command.h"
#include "exec_cmd.h"
#include "utf8.h"
#include "parse-options.h"
-#include "cache-tree.h"
#include "diff.h"
#include "revision.h"
#include "rerere.h"
-#include "merge-recursive.h"
+#include "pick.h"
/*
* This implements the builtins revert and cherry-pick.
@@ -35,25 +31,23 @@ static const char * const cherry_pick_usage[] = {
NULL
};
-static int edit, no_replay, no_commit, mainline, signoff;
-static enum { REVERT, CHERRY_PICK } action;
+static int edit, no_commit, mainline, signoff;
+static int flags;
static struct commit *commit;
-static const char *me;
-
#define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
static void parse_args(int argc, const char **argv)
{
const char * const * usage_str =
- action == REVERT ? revert_usage : cherry_pick_usage;
+ flags & PICK_REVERSE ? revert_usage : cherry_pick_usage;
unsigned char sha1[20];
const char *arg;
int noop;
struct option options[] = {
OPT_BOOLEAN('n', "no-commit", &no_commit, "don't automatically commit"),
OPT_BOOLEAN('e', "edit", &edit, "edit the commit message"),
- OPT_BOOLEAN('x', NULL, &no_replay, "append commit name when cherry-picking"),
+ OPT_BIT('x', NULL, &flags, "append commit name when cherry-picking", PICK_ADD_NOTE),
OPT_BOOLEAN('r', NULL, &noop, "no-op (backward compatibility)"),
OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"),
OPT_INTEGER('m', "mainline", &mainline, "parent number"),
@@ -77,42 +71,12 @@ static void parse_args(int argc, const char **argv)
die ("'%s' does not point to a commit", arg);
}
-static char *get_oneline(const char *message)
-{
- char *result;
- const char *p = message, *abbrev, *eol;
- int abbrev_len, oneline_len;
-
- if (!p)
- die ("Could not read commit message of %s",
- sha1_to_hex(commit->object.sha1));
- while (*p && (*p != '\n' || p[1] != '\n'))
- p++;
-
- if (*p) {
- p += 2;
- for (eol = p + 1; *eol && *eol != '\n'; eol++)
- ; /* do nothing */
- } else
- eol = p;
- abbrev = find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV);
- abbrev_len = strlen(abbrev);
- oneline_len = eol - p;
- result = xmalloc(abbrev_len + 5 + oneline_len);
- memcpy(result, abbrev, abbrev_len);
- memcpy(result + abbrev_len, "... ", 4);
- memcpy(result + abbrev_len + 4, p, oneline_len);
- result[abbrev_len + 4 + oneline_len] = '\0';
- return result;
-}
-
static char *get_encoding(const char *message)
{
const char *p = message, *eol;
if (!p)
- die ("Could not read commit message of %s",
- sha1_to_hex(commit->object.sha1));
+ return NULL;
while (*p && *p != '\n') {
for (eol = p + 1; *eol && *eol != '\n'; eol++)
; /* do nothing */
@@ -128,30 +92,6 @@ static char *get_encoding(const char *message)
return NULL;
}
-static struct lock_file msg_file;
-static int msg_fd;
-
-static void add_to_msg(const char *string)
-{
- int len = strlen(string);
- if (write_in_full(msg_fd, string, len) < 0)
- die_errno ("Could not write to MERGE_MSG");
-}
-
-static void add_message_to_msg(const char *message)
-{
- const char *p = message;
- while (*p && (*p != '\n' || p[1] != '\n'))
- p++;
-
- if (!*p)
- add_to_msg(sha1_to_hex(commit->object.sha1));
-
- p += 2;
- add_to_msg(p);
- return;
-}
-
static void set_author_ident_env(const char *message)
{
const char *p = message;
@@ -214,7 +154,7 @@ static char *help_msg(const unsigned char *sha1)
"mark the corrected paths with 'git add <paths>' "
"or 'git rm <paths>' and commit the result.");
- if (action == CHERRY_PICK) {
+ if (!(flags & PICK_REVERSE)) {
sprintf(helpbuf + strlen(helpbuf),
"\nWhen commiting, use the option "
"'-c %s' to retain authorship and message.",
@@ -223,187 +163,68 @@ static char *help_msg(const unsigned char *sha1)
return helpbuf;
}
-static struct tree *empty_tree(void)
+static void write_message(struct strbuf *msgbuf, const char *filename)
{
- struct tree *tree = xcalloc(1, sizeof(struct tree));
-
- tree->object.parsed = 1;
- tree->object.type = OBJ_TREE;
- pretend_sha1_file(NULL, 0, OBJ_TREE, tree->object.sha1);
- return tree;
+ struct lock_file msg_file;
+ int msg_fd;
+ msg_fd = hold_lock_file_for_update(&msg_file, filename,
+ LOCK_DIE_ON_ERROR);
+ if (write_in_full(msg_fd, msgbuf->buf, msgbuf->len) < 0)
+ die_errno("Could not write to %s.", filename);
+ strbuf_release(msgbuf);
+ if (commit_lock_file(&msg_file) < 0)
+ die("Error wrapping up %s", filename);
}
static int revert_or_cherry_pick(int argc, const char **argv)
{
- unsigned char head[20];
- struct commit *base, *next, *parent;
- int i, index_fd, clean;
- char *oneline, *reencoded_message = NULL;
- const char *message, *encoding;
- char *defmsg = git_pathdup("MERGE_MSG");
- struct merge_options o;
- struct tree *result, *next_tree, *base_tree, *head_tree;
- static struct lock_file index_lock;
+ const char *me;
+ struct strbuf msgbuf;
+ char *reencoded_message = NULL;
+ const char *encoding;
+ int failed;
git_config(git_default_config, NULL);
- me = action == REVERT ? "revert" : "cherry-pick";
+ me = flags & PICK_REVERSE ? "revert" : "cherry-pick";
setenv(GIT_REFLOG_ACTION, me, 0);
parse_args(argc, argv);
- /* this is copied from the shell script, but it's never triggered... */
- if (action == REVERT && !no_replay)
- die("revert is incompatible with replay");
-
if (read_cache() < 0)
die("git %s: failed to read the index", me);
- if (no_commit) {
- /*
- * We do not intend to commit immediately. We just want to
- * merge the differences in, so let's compute the tree
- * that represents the "current" state for merge-recursive
- * to work on.
- */
- if (write_cache_as_tree(head, 0, NULL))
- die ("Your index file is unmerged.");
- } else {
- if (get_sha1("HEAD", head))
- die ("You do not have a valid HEAD");
- if (index_differs_from("HEAD", 0))
- die ("Dirty index: cannot %s", me);
- }
- discard_cache();
-
- index_fd = hold_locked_index(&index_lock, 1);
+ if (!no_commit && index_differs_from("HEAD", 0))
+ die ("Dirty index: cannot %s", me);
- if (!commit->parents) {
- if (action == REVERT)
- die ("Cannot revert a root commit");
- parent = NULL;
- }
- else if (commit->parents->next) {
- /* Reverting or cherry-picking a merge commit */
- int cnt;
- struct commit_list *p;
-
- if (!mainline)
- die("Commit %s is a merge but no -m option was given.",
- sha1_to_hex(commit->object.sha1));
-
- for (cnt = 1, p = commit->parents;
- cnt != mainline && p;
- cnt++)
- p = p->next;
- if (cnt != mainline || !p)
- die("Commit %s does not have parent %d",
- sha1_to_hex(commit->object.sha1), mainline);
- parent = p->item;
- } else if (0 < mainline)
- die("Mainline was specified but commit %s is not a merge.",
- sha1_to_hex(commit->object.sha1));
- else
- parent = commit->parents->item;
-
- if (!(message = commit->buffer))
- die ("Cannot get commit message for %s",
+ if (!commit->buffer)
+ return error("Cannot get commit message for %s",
sha1_to_hex(commit->object.sha1));
-
- if (parent && parse_commit(parent) < 0)
- die("%s: cannot parse parent commit %s",
- me, sha1_to_hex(parent->object.sha1));
-
- /*
- * "commit" is an existing commit. We would want to apply
- * the difference it introduces since its first parent "prev"
- * on top of the current HEAD if we are cherry-pick. Or the
- * reverse of it if we are revert.
- */
-
- msg_fd = hold_lock_file_for_update(&msg_file, defmsg,
- LOCK_DIE_ON_ERROR);
-
- encoding = get_encoding(message);
+ encoding = get_encoding(commit->buffer);
if (!encoding)
encoding = "UTF-8";
if (!git_commit_encoding)
git_commit_encoding = "UTF-8";
- if ((reencoded_message = reencode_string(message,
+ if ((reencoded_message = reencode_string(commit->buffer,
git_commit_encoding, encoding)))
- message = reencoded_message;
-
- oneline = get_oneline(message);
-
- if (action == REVERT) {
- char *oneline_body = strchr(oneline, ' ');
+ commit->buffer = reencoded_message;
- base = commit;
- next = parent;
- add_to_msg("Revert \"");
- add_to_msg(oneline_body + 1);
- add_to_msg("\"\n\nThis reverts commit ");
- add_to_msg(sha1_to_hex(commit->object.sha1));
-
- if (commit->parents->next) {
- add_to_msg(", reversing\nchanges made to ");
- add_to_msg(sha1_to_hex(parent->object.sha1));
- }
- add_to_msg(".\n");
- } else {
- base = parent;
- next = commit;
- set_author_ident_env(message);
- add_message_to_msg(message);
- if (no_replay) {
- add_to_msg("(cherry picked from commit ");
- add_to_msg(sha1_to_hex(commit->object.sha1));
- add_to_msg(")\n");
- }
- }
-
- read_cache();
- init_merge_options(&o);
- o.branch1 = "HEAD";
- o.branch2 = oneline;
-
- head_tree = parse_tree_indirect(head);
- next_tree = next ? next->tree : empty_tree();
- base_tree = base ? base->tree : empty_tree();
-
- clean = merge_trees(&o,
- head_tree,
- next_tree, base_tree, &result);
-
- if (active_cache_changed &&
- (write_cache(index_fd, active_cache, active_nr) ||
- commit_locked_index(&index_lock)))
- die("%s: Unable to write new index file", me);
- rollback_lock_file(&index_lock);
-
- if (!clean) {
- add_to_msg("\nConflicts:\n\n");
- for (i = 0; i < active_nr;) {
- struct cache_entry *ce = active_cache[i++];
- if (ce_stage(ce)) {
- add_to_msg("\t");
- add_to_msg(ce->name);
- add_to_msg("\n");
- while (i < active_nr && !strcmp(ce->name,
- active_cache[i]->name))
- i++;
- }
- }
- if (commit_lock_file(&msg_file) < 0)
- die ("Error wrapping up %s", defmsg);
+ failed = pick_commit(commit, mainline, flags, &msgbuf);
+ if (failed < 0) {
+ exit(1);
+ } else if (failed > 0) {
fprintf(stderr, "Automatic %s failed.%s\n",
me, help_msg(commit->object.sha1));
+ write_message(&msgbuf, git_path("MERGE_MSG"));
rerere();
exit(1);
}
- if (commit_lock_file(&msg_file) < 0)
- die ("Error wrapping up %s", defmsg);
+ if (!(flags & PICK_REVERSE))
+ set_author_ident_env(commit->buffer);
+ free(reencoded_message);
+
fprintf(stderr, "Finished one %s.\n", me);
+ write_message(&msgbuf, git_path("MERGE_MSG"));
+
/*
- *
* If we are cherry-pick, and if the merge did not result in
* hand-editing, we will hit this commit and inherit the original
* author date and name.
@@ -421,14 +242,11 @@ static int revert_or_cherry_pick(int argc, const char **argv)
args[i++] = "-s";
if (!edit) {
args[i++] = "-F";
- args[i++] = defmsg;
+ args[i++] = git_path("MERGE_MSG");
}
args[i] = NULL;
return execv_git_cmd(args);
}
- free(reencoded_message);
- free(defmsg);
-
return 0;
}
@@ -436,14 +254,12 @@ int cmd_revert(int argc, const char **argv, const char *prefix)
{
if (isatty(0))
edit = 1;
- no_replay = 1;
- action = REVERT;
+ flags = PICK_REVERSE | PICK_ADD_NOTE;
return revert_or_cherry_pick(argc, argv);
}
int cmd_cherry_pick(int argc, const char **argv, const char *prefix)
{
- no_replay = 0;
- action = CHERRY_PICK;
+ flags = 0;
return revert_or_cherry_pick(argc, argv);
}
diff --git a/pick.c b/pick.c
new file mode 100644
index 0000000..058b877
--- /dev/null
+++ b/pick.c
@@ -0,0 +1,210 @@
+#include "cache.h"
+#include "commit.h"
+#include "run-command.h"
+#include "cache-tree.h"
+#include "pick.h"
+#include "merge-recursive.h"
+
+static struct commit *commit;
+
+static char *get_oneline(const char *message)
+{
+ char *result;
+ const char *p = message, *abbrev, *eol;
+ int abbrev_len, oneline_len;
+
+ if (!p)
+ return NULL;
+ while (*p && (*p != '\n' || p[1] != '\n'))
+ p++;
+
+ if (*p) {
+ p += 2;
+ for (eol = p + 1; *eol && *eol != '\n'; eol++)
+ ; /* do nothing */
+ } else
+ eol = p;
+ abbrev = find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV);
+ abbrev_len = strlen(abbrev);
+ oneline_len = eol - p;
+ result = xmalloc(abbrev_len + 5 + oneline_len);
+ memcpy(result, abbrev, abbrev_len);
+ memcpy(result + abbrev_len, "... ", 4);
+ memcpy(result + abbrev_len + 4, p, oneline_len);
+ result[abbrev_len + 4 + oneline_len] = '\0';
+ return result;
+}
+
+static void add_message_to_msg(struct strbuf *msg, const char *message)
+{
+ const char *p = message;
+ while (*p && (*p != '\n' || p[1] != '\n'))
+ p++;
+
+ if (!*p)
+ strbuf_addstr(msg, sha1_to_hex(commit->object.sha1));
+
+ p += 2;
+ strbuf_addstr(msg, p);
+ return;
+}
+
+static struct tree *empty_tree(void)
+{
+ struct tree *tree = xcalloc(1, sizeof(struct tree));
+
+ tree->object.parsed = 1;
+ tree->object.type = OBJ_TREE;
+ pretend_sha1_file(NULL, 0, OBJ_TREE, tree->object.sha1);
+ return tree;
+}
+
+/*
+ * Pick changes introduced by "commit" argument into current working
+ * tree and index.
+ *
+ * Return 0 on success.
+ * Return negative value on error before picking,
+ * and a positive value after picking,
+ * and return 1 if and only if a conflict occurs but no other error.
+ */
+int pick_commit(struct commit *pick_commit, int mainline, int flags,
+ struct strbuf *msg)
+{
+ unsigned char head[20];
+ struct commit *base, *next, *parent;
+ int i, index_fd, clean;
+ int ret = 0;
+ char *oneline;
+ const char *message;
+ struct merge_options o;
+ struct tree *result, *next_tree, *base_tree, *head_tree;
+ static struct lock_file index_lock;
+
+ strbuf_init(msg, 0);
+ commit = pick_commit;
+
+ /*
+ * Let's compute the tree that represents the "current" state
+ * for merge-recursive to work on.
+ */
+ if (write_cache_as_tree(head, 0, NULL))
+ return error("Your index file is unmerged.");
+ discard_cache();
+
+ index_fd = hold_locked_index(&index_lock, 0);
+ if (index_fd < 0)
+ return error("Unable to create locked index: %s",
+ strerror(errno));
+
+ if (!commit->parents) {
+ if (flags & PICK_REVERSE)
+ return error("Cannot revert a root commit");
+ parent = NULL;
+ }
+ else if (commit->parents->next) {
+ /* Reverting or cherry-picking a merge commit */
+ int cnt;
+ struct commit_list *p;
+
+ if (!mainline)
+ return error("Commit %s is a merge but no mainline was given.",
+ sha1_to_hex(commit->object.sha1));
+
+ for (cnt = 1, p = commit->parents;
+ cnt != mainline && p;
+ cnt++)
+ p = p->next;
+ if (cnt != mainline || !p)
+ return error("Commit %s does not have parent %d",
+ sha1_to_hex(commit->object.sha1),
+ mainline);
+ parent = p->item;
+ } else if (0 < mainline)
+ return error("Mainline was specified but commit %s is not a merge.",
+ sha1_to_hex(commit->object.sha1));
+ else
+ parent = commit->parents->item;
+
+ if (!(message = commit->buffer))
+ return error("Cannot get commit message for %s",
+ sha1_to_hex(commit->object.sha1));
+
+ if (parent && parse_commit(parent) < 0)
+ return error("Cannot parse parent commit %s",
+ sha1_to_hex(parent->object.sha1));
+
+ oneline = get_oneline(message);
+
+ if (flags & PICK_REVERSE) {
+ char *oneline_body = strchr(oneline, ' ');
+
+ base = commit;
+ next = parent;
+ strbuf_addstr(msg, "Revert \"");
+ strbuf_addstr(msg, oneline_body + 1);
+ strbuf_addstr(msg, "\"\n\nThis reverts commit ");
+ strbuf_addstr(msg, sha1_to_hex(commit->object.sha1));
+
+ if (commit->parents->next) {
+ strbuf_addstr(msg, ", reversing\nchanges made to ");
+ strbuf_addstr(msg, sha1_to_hex(parent->object.sha1));
+ }
+ strbuf_addstr(msg, ".\n");
+ } else {
+ base = parent;
+ next = commit;
+ add_message_to_msg(msg, message);
+ if (flags & PICK_ADD_NOTE) {
+ strbuf_addstr(msg, "(cherry picked from commit ");
+ strbuf_addstr(msg, sha1_to_hex(commit->object.sha1));
+ strbuf_addstr(msg, ")\n");
+ }
+ }
+
+ read_cache();
+ init_merge_options(&o);
+ o.branch1 = "HEAD";
+ o.branch2 = oneline;
+
+ head_tree = parse_tree_indirect(head);
+ next_tree = next ? next->tree : empty_tree();
+ base_tree = base ? base->tree : empty_tree();
+
+ clean = merge_trees(&o,
+ head_tree,
+ next_tree, base_tree, &result);
+
+ if (active_cache_changed &&
+ (write_cache(index_fd, active_cache, active_nr) ||
+ commit_locked_index(&index_lock))) {
+ error("Unable to write new index file");
+ return 2;
+ }
+ rollback_lock_file(&index_lock);
+
+ if (!clean) {
+ strbuf_addstr(msg, "\nConflicts:\n\n");
+ for (i = 0; i < active_nr;) {
+ struct cache_entry *ce = active_cache[i++];
+ if (ce_stage(ce)) {
+ strbuf_addstr(msg, "\t");
+ strbuf_addstr(msg, ce->name);
+ strbuf_addstr(msg, "\n");
+ while (i < active_nr && !strcmp(ce->name,
+ active_cache[i]->name))
+ i++;
+ }
+ }
+ ret = 1;
+ }
+ free(oneline);
+
+ discard_cache();
+ if (read_cache() < 0) {
+ error("Cannot read the index");
+ return 2;
+ }
+
+ return ret;
+}
diff --git a/pick.h b/pick.h
new file mode 100644
index 0000000..7a74ad8
--- /dev/null
+++ b/pick.h
@@ -0,0 +1,13 @@
+#ifndef PICK_H
+#define PICK_H
+
+#include "commit.h"
+
+/* Pick flags: */
+#define PICK_REVERSE 1 /* pick the reverse changes ("revert") */
+#define PICK_ADD_NOTE 2 /* add note about original commit (unless conflict) */
+/* We don't need a PICK_QUIET. This is done by
+ * setenv("GIT_MERGE_VERBOSITY", "0", 1); */
+extern int pick_commit(struct commit *commit, int mainline, int flags, struct strbuf *msg);
+
+#endif
--
1.6.4.271.ge010d
^ permalink raw reply related
* [PATCH v2 7/9] sequencer: add "do_commit()" and related functions
From: Christian Couder @ 2009-08-21 5:49 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Johannes Schindelin, Stephan Beyer, Daniel Barkalow,
Jakub Narebski
In-Reply-To: <20090821054729.3726.5078.chriscool@tuxfamily.org>
From: Stephan Beyer <s-beyer@gmx.net>
This patch adds some code that comes from the sequencer GSoC project:
git://repo.or.cz/git/sbeyer.git
(commit 5a78908b70ceb5a4ea9fd4b82f07ceba1f019079)
It adds "struct commit_info", the "next_commit" static variable and
the following functions:
- do_commit()
- set_author_info()
- set_message_source()
- set_pick_subject()
- write_commit_summary_into()
This makes it possible to prepare and perform a commit.
Compared to the sequencer project, the only change is that "mark"
related (3 lines long) code has been removed from do_commit().
Mentored-by: Daniel Barkalow <barkalow@iabervon.org>
Mentored-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Stephan Beyer <s-beyer@gmx.net>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
builtin-sequencer--helper.c | 214 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 214 insertions(+), 0 deletions(-)
diff --git a/builtin-sequencer--helper.c b/builtin-sequencer--helper.c
index 71a7fef..61a8f2e 100644
--- a/builtin-sequencer--helper.c
+++ b/builtin-sequencer--helper.c
@@ -5,26 +5,69 @@
#include "refs.h"
#include "diff.h"
#include "unpack-trees.h"
+#include "string-list.h"
+#include "pick.h"
+#include "rerere.h"
+#include "dir.h"
+#include "cache-tree.h"
+#include "utf8.h"
#define SEQ_DIR "rebase-merge"
#define PATCH_FILE git_path(SEQ_DIR "/patch")
+#define MERGE_MSG git_path("MERGE_MSG")
+#define SQUASH_MSG git_path("SQUASH_MSG")
+
+/**********************************************************************
+ * Data structures
+ */
+
+struct user_info {
+ const char *name;
+ const char *mail;
+ const char *time; /* "<timestamp> <timezone>" */
+};
+
+struct commit_info {
+ struct user_info author; /* author info */
+ struct user_info committer; /* not used, but for easy extendability */
+ const char *encoding; /* encoding */
+ char *subject; /* basically the first line of the summary */
+ struct strbuf summary; /* the commit message */
+ char *source; /* source of the commit message, either
+ * "message", "merge", "squash" or a commit SHA1 */
+ char *patch; /* a patch */
+ struct string_list parents; /* list of parents' hex'ed sha1 ids */
+};
+
+/**********************************************************************
+ * Global variables
+ */
static char *reflog;
+static int squash_count = 0;
+
static int allow_dirty = 0, verbosity = 1, advice = 1;
static unsigned char head_sha1[20];
+static struct commit_info next_commit;
+
static const char * const git_sequencer_helper_usage[] = {
"git sequencer--helper --make-patch <commit>",
"git sequencer--helper --reset-hard <commit> <reflog-msg> "
"<verbosity> [<allow-dirty>]",
"git sequencer--helper --fast-forward <commit> <reflog-msg> "
"<verbosity> [<allow-dirty>]",
+ "git sequencer--helper --cherry-pick <commit> [<do-not-commit>]",
NULL
};
+/**********************************************************************
+ * Sequencer functions
+ */
+
static int parse_and_init_tree_desc(const unsigned char *sha1,
struct tree_desc *desc)
{
@@ -162,6 +205,157 @@ static void make_patch(struct commit *commit)
free(args);
}
+/* Commit current index with information next_commit onto parent_sha1. */
+static int do_commit(unsigned char *parent_sha1)
+{
+ int failed;
+ unsigned char tree_sha1[20];
+ unsigned char commit_sha1[20];
+ struct strbuf sbuf;
+ const char *reencoded = NULL;
+
+ if (squash_count) {
+ squash_count = 0;
+ if (file_exists(SQUASH_MSG))
+ unlink(SQUASH_MSG);
+ }
+
+ if (!index_differs_from("HEAD", 0) &&
+ !next_commit.parents.nr)
+ return error("No changes! Do you really want an empty commit?");
+
+ if (!next_commit.author.name || !next_commit.author.mail)
+ return error("Internal error: Author information not set properly.");
+
+ if (write_cache_as_tree(tree_sha1, 0, NULL))
+ return 1;
+
+ if (!next_commit.encoding)
+ next_commit.encoding = xstrdup("utf-8");
+ if (!git_commit_encoding)
+ git_commit_encoding = "utf-8";
+
+ strbuf_init(&sbuf, 8192); /* should avoid reallocs for the headers */
+ strbuf_addf(&sbuf, "tree %s\n", sha1_to_hex(tree_sha1));
+ if (parent_sha1)
+ strbuf_addf(&sbuf, "parent %s\n", sha1_to_hex(parent_sha1));
+ if (next_commit.parents.nr) {
+ int i;
+ for (i = 0; i < next_commit.parents.nr; ++i)
+ strbuf_addf(&sbuf, "parent %s\n",
+ next_commit.parents.items[i].string);
+ }
+ if (!next_commit.author.time) {
+ char time[50];
+ datestamp(time, sizeof(time));
+ next_commit.author.time = xstrdup(time);
+ }
+
+ stripspace(&next_commit.summary, 1);
+
+ /* if encodings differ, reencode whole buffer */
+ if (strcasecmp(git_commit_encoding, next_commit.encoding)) {
+ if ((reencoded = reencode_string(next_commit.author.name,
+ git_commit_encoding, next_commit.encoding))) {
+ free((void *)next_commit.author.name);
+ next_commit.author.name = reencoded;
+ }
+ if ((reencoded = reencode_string(next_commit.summary.buf,
+ git_commit_encoding, next_commit.encoding))) {
+ strbuf_reset(&next_commit.summary);
+ strbuf_addstr(&next_commit.summary, reencoded);
+ }
+ }
+ strbuf_addf(&sbuf, "author %s <%s> %s\n", next_commit.author.name,
+ next_commit.author.mail, next_commit.author.time);
+ strbuf_addf(&sbuf, "committer %s\n", git_committer_info(0));
+ if (!is_encoding_utf8(git_commit_encoding))
+ strbuf_addf(&sbuf, "encoding %s\n", git_commit_encoding);
+ strbuf_addch(&sbuf, '\n');
+ strbuf_addbuf(&sbuf, &next_commit.summary);
+ if (sbuf.buf[sbuf.len-1] != '\n')
+ strbuf_addch(&sbuf, '\n');
+
+ failed = write_sha1_file(sbuf.buf, sbuf.len, commit_type, commit_sha1);
+ strbuf_release(&sbuf);
+ if (failed)
+ return 1;
+
+ if (verbosity > 1)
+ printf("Created %scommit %s\n",
+ parent_sha1 || next_commit.parents.nr ? "" : "initial ",
+ sha1_to_hex(commit_sha1));
+
+ if (update_ref(reflog, "HEAD", commit_sha1, NULL, 0, 0))
+ return error("Could not update HEAD to %s.",
+ sha1_to_hex(commit_sha1));
+
+ return 0;
+}
+
+/*
+ * Fill next_commit.author according to ident.
+ * Ident may have one of the following forms:
+ * "name <e-mail> timestamp timezone\n..."
+ * "name <e-mail> timestamp timezone"
+ * "name <e-mail>"
+ */
+static void set_author_info(const char *ident)
+{
+ const char *tmp1 = strstr(ident, " <");
+ const char *tmp2;
+ char *data;
+ if (!tmp1)
+ return;
+ tmp2 = strstr(tmp1+2, ">");
+ if (!tmp2)
+ return;
+ if (tmp2[1] != 0 && tmp2[1] != ' ')
+ return;
+
+ data = xmalloc(strlen(ident)); /* a trivial upper bound */
+
+ snprintf(data, tmp1-ident+1, "%s", ident);
+ next_commit.author.name = xstrdup(data);
+ snprintf(data, tmp2-tmp1-1, "%s", tmp1+2);
+ next_commit.author.mail = xstrdup(data);
+
+ if (tmp2[1] == 0) {
+ free(data);
+ return;
+ }
+
+ tmp1 = strpbrk(tmp2+2, "\r\n");
+ if (!tmp1)
+ tmp1 = tmp2 + strlen(tmp2);
+
+ snprintf(data, tmp1-tmp2-1, "%s", tmp2+2);
+ next_commit.author.time = xstrdup(data);
+ free(data);
+}
+
+static void set_message_source(const char *source)
+{
+ if (next_commit.source)
+ free(next_commit.source);
+ next_commit.source = xstrdup(source);
+}
+
+/* Set subject, an information for the case of conflict */
+static void set_pick_subject(const char *hex, struct commit *commit)
+{
+ const char *tmp = strstr(commit->buffer, "\n\n");
+ if (tmp) {
+ const char *eol;
+ int len = strlen(hex);
+ tmp += 2;
+ eol = strchrnul(tmp, '\n');
+ next_commit.subject = xmalloc(eol - tmp + len + 5);
+ snprintf(next_commit.subject, eol - tmp + len + 5, "%s... %s",
+ hex, tmp);
+ }
+}
+
/* Return a commit object of "arg" */
static struct commit *get_commit(const char *arg)
{
@@ -198,6 +392,26 @@ static int set_verbosity(int verbose)
return 0;
}
+static int write_commit_summary_into(const char *filename)
+{
+ struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
+ int fd = hold_lock_file_for_update(lock, filename, 0);
+ if (fd < 0)
+ return error("Unable to create '%s.lock': %s", filename,
+ strerror(errno));
+ if (write_in_full(fd, next_commit.summary.buf,
+ next_commit.summary.len) < 0)
+ return error("Could not write to %s: %s",
+ filename, strerror(errno));
+ if (commit_lock_file(lock) < 0)
+ return error("Error wrapping up %s", filename);
+ return 0;
+}
+
+/**********************************************************************
+ * Builtin sequencer helper functions
+ */
+
/* v should be "" or "t" or "\d" */
static int parse_verbosity(const char *v)
{
--
1.6.4.271.ge010d
^ permalink raw reply related
* [PATCH v2 9/9] rebase -i: use "git sequencer--helper --cherry-pick"
From: Christian Couder @ 2009-08-21 5:50 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Johannes Schindelin, Stephan Beyer, Daniel Barkalow,
Jakub Narebski
In-Reply-To: <20090821054729.3726.5078.chriscool@tuxfamily.org>
instead of "git cherry-pick", as this will make it easier to
port "git-rebase--interactive.sh" to C.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
git-rebase--interactive.sh | 11 ++++++++---
1 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 7651fd6..349ca50 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -147,7 +147,8 @@ pick_one () {
pick_one_preserving_merges "$@" && return
if test ! -z "$REBASE_ROOT"
then
- output git cherry-pick "$@"
+ git sequencer--helper --cherry-pick $sha1 \
+ "$GIT_REFLOG_ACTION" "$VERBOSE" $no_ff
return
fi
parent_sha1=$(git rev-parse --verify $sha1^) ||
@@ -157,7 +158,8 @@ pick_one () {
git sequencer--helper --fast-forward $sha1 \
"$GIT_REFLOG_ACTION" "$VERBOSE"
else
- output git cherry-pick "$@"
+ git sequencer--helper --cherry-pick $sha1 \
+ "$GIT_REFLOG_ACTION" "$VERBOSE" $no_ff
fi
}
@@ -269,7 +271,10 @@ pick_one_preserving_merges () {
fi
;;
*)
- output git cherry-pick "$@" ||
+ no_commit=
+ test "a$1" = "a-n" && no_commit=t
+ git sequencer--helper --cherry-pick $sha1 \
+ "$GIT_REFLOG_ACTION" "$VERBOSE" $no_commit ||
die_with_patch $sha1 "Could not pick $sha1"
;;
esac
--
1.6.4.271.ge010d
^ permalink raw reply related
* [PATCH v2 0/9] more changes to port rebase -i to C using sequencer code
From: Christian Couder @ 2009-08-21 5:49 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Johannes Schindelin, Stephan Beyer, Daniel Barkalow,
Jakub Narebski
This is a reroll of the series I sent 9 days ago.
Patch 5/9 (revert: libify pick) now contains some fixups suggested by
Junio, so it's based on a newer commit in the sequencer repo.
I also updated the commit message of some following patches so they
display the same commit sha1 from the sequencer repo.
Patch 8/9 has been reworked so that the --cherry-pick option use the
same arguments as other options.
Christian Couder (5):
sequencer: add "--fast-forward" option to "git sequencer--helper"
sequencer: let "git sequencer--helper" callers set "allow_dirty"
rebase -i: use "git sequencer--helper --fast-forward"
pick: libify "pick_help_msg()"
rebase -i: use "git sequencer--helper --cherry-pick"
Stephan Beyer (4):
sequencer: add "do_fast_forward()" to perform a fast forward
revert: libify pick
sequencer: add "do_commit()" and related functions
sequencer: add "--cherry-pick" option to "git sequencer--helper"
Makefile | 2 +
builtin-revert.c | 293 ++++++-----------------------------------
builtin-sequencer--helper.c | 305 +++++++++++++++++++++++++++++++++++++++++--
git-rebase--interactive.sh | 22 ++--
pick.c | 232 ++++++++++++++++++++++++++++++++
pick.h | 14 ++
6 files changed, 599 insertions(+), 269 deletions(-)
create mode 100644 pick.c
create mode 100644 pick.h
^ permalink raw reply
* [PATCH v2 6/9] pick: libify "pick_help_msg()"
From: Christian Couder @ 2009-08-21 5:49 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Johannes Schindelin, Stephan Beyer, Daniel Barkalow,
Jakub Narebski
In-Reply-To: <20090821054729.3726.5078.chriscool@tuxfamily.org>
This function gives an help message when pick or revert failed.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
builtin-revert.c | 23 +----------------------
pick.c | 22 ++++++++++++++++++++++
pick.h | 1 +
3 files changed, 24 insertions(+), 22 deletions(-)
diff --git a/builtin-revert.c b/builtin-revert.c
index 4797ac5..e5250bd 100644
--- a/builtin-revert.c
+++ b/builtin-revert.c
@@ -142,27 +142,6 @@ static void set_author_ident_env(const char *message)
sha1_to_hex(commit->object.sha1));
}
-static char *help_msg(const unsigned char *sha1)
-{
- static char helpbuf[1024];
- char *msg = getenv("GIT_CHERRY_PICK_HELP");
-
- if (msg)
- return msg;
-
- strcpy(helpbuf, " After resolving the conflicts,\n"
- "mark the corrected paths with 'git add <paths>' "
- "or 'git rm <paths>' and commit the result.");
-
- if (!(flags & PICK_REVERSE)) {
- sprintf(helpbuf + strlen(helpbuf),
- "\nWhen commiting, use the option "
- "'-c %s' to retain authorship and message.",
- find_unique_abbrev(sha1, DEFAULT_ABBREV));
- }
- return helpbuf;
-}
-
static void write_message(struct strbuf *msgbuf, const char *filename)
{
struct lock_file msg_file;
@@ -211,7 +190,7 @@ static int revert_or_cherry_pick(int argc, const char **argv)
exit(1);
} else if (failed > 0) {
fprintf(stderr, "Automatic %s failed.%s\n",
- me, help_msg(commit->object.sha1));
+ me, pick_help_msg(commit->object.sha1, flags));
write_message(&msgbuf, git_path("MERGE_MSG"));
rerere();
exit(1);
diff --git a/pick.c b/pick.c
index 058b877..4f882bb 100644
--- a/pick.c
+++ b/pick.c
@@ -208,3 +208,25 @@ int pick_commit(struct commit *pick_commit, int mainline, int flags,
return ret;
}
+
+char *pick_help_msg(const unsigned char *sha1, int flags)
+{
+ static char helpbuf[1024];
+ char *msg = getenv("GIT_CHERRY_PICK_HELP");
+
+ if (msg)
+ return msg;
+
+ strcpy(helpbuf, " After resolving the conflicts,\n"
+ "mark the corrected paths with 'git add <paths>' "
+ "or 'git rm <paths>' and commit the result.");
+
+ if (!(flags & PICK_REVERSE)) {
+ sprintf(helpbuf + strlen(helpbuf),
+ "\nWhen commiting, use the option "
+ "'-c %s' to retain authorship and message.",
+ find_unique_abbrev(sha1, DEFAULT_ABBREV));
+ }
+ return helpbuf;
+}
+
diff --git a/pick.h b/pick.h
index 7a74ad8..115541a 100644
--- a/pick.h
+++ b/pick.h
@@ -9,5 +9,6 @@
/* We don't need a PICK_QUIET. This is done by
* setenv("GIT_MERGE_VERBOSITY", "0", 1); */
extern int pick_commit(struct commit *commit, int mainline, int flags, struct strbuf *msg);
+extern char *pick_help_msg(const unsigned char *sha1, int flags);
#endif
--
1.6.4.271.ge010d
^ permalink raw reply related
* [PATCH] Add support for the Mongoose web server.
From: Wilhansen Li @ 2009-08-21 6:39 UTC (permalink / raw)
To: git
Mongoose (http://code.google.com/p/mongoose/) is a lightweight web
server. It's just a single binary so it's a lot simpler to configure and
install.
Signed-off-by: Wilhansen Li <wil@nohakostudios.net>
---
git-instaweb.sh | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 53 insertions(+), 5 deletions(-)
diff --git a/git-instaweb.sh b/git-instaweb.sh
index 5f5cac7..2acf707 100755
--- a/git-instaweb.sh
+++ b/git-instaweb.sh
@@ -77,11 +77,30 @@ start_httpd () {
resolve_full_httpd
# don't quote $full_httpd, there can be arguments to it (-f)
- $full_httpd "$fqgitdir/gitweb/httpd.conf"
- if test $? != 0; then
- echo "Could not execute http daemon $httpd."
- exit 1
- fi
+ case "$httpd" in
+ *mongoose*)
+ #The mongoose server doesn't have a daemon mode so we'll have to fork it
+ $full_httpd "$fqgitdir/gitweb/httpd.conf" &
+ #Save the pid before doing anything else (we'll print it later)
+ pid=$!
+
+ if test $? != 0; then
+ echo "Could not execute http daemon $httpd."
+ exit 1
+ fi
+
+ cat > "$fqgitdir/pid" <<EOF
+$pid
+EOF
+ ;;
+ *)
+ $full_httpd "$fqgitdir/gitweb/httpd.conf"
+ if test $? != 0; then
+ echo "Could not execute http daemon $httpd."
+ exit 1
+ fi
+ ;;
+ esac
}
stop_httpd () {
@@ -308,6 +327,32 @@ EOF
fi
}
+mongoose_conf() {
+ cat > "$conf" <<EOF
+# Mongoose web server configuration file.
+# Lines starting with '#' and empty lines are ignored.
+# For detailed description of every option, visit
+# http://code.google.com/p/mongoose/wiki/MongooseManual
+
+root $fqgitdir/gitweb
+ports $port
+index_files gitweb.cgi
+#ssl_cert $fqgitdir/gitweb/ssl_cert.pem
+error_log $fqgitdir/gitweb/error.log
+access_log $fqgitdir/gitweb/access.log
+
+#cgi setup
+cgi_env PATH=/usr/local/bin:/usr/bin:/bin,GIT_DIR=$GIT_DIR,GIT_EXEC_PATH=$GIT_EXEC_PATH
+cgi_interp $PERL
+cgi_ext cgi,pl
+
+# mimetype mapping
+mime_types .gz=application/x-gzip,.tar.gz=application/x-tgz,.tgz=application/x-tgz,.tar=application/x-tar,.zip=application/zip,.gif=image/gif,.jpg=image/jpeg,.jpeg=image/jpeg,.png=image/png,.css=text/css,.html=text/html,.htm=text/html,.js=text/javascript,.c=text/plain,.cpp=text/plain,.log=text/plain,.conf=text/plain,.text=text/plain,.txt=text/plain,.dtd=text/xml,.bz2=application/x-bzip,.tbz=application/x-bzip-compressed-tar,.tar.bz2=application/x-bzip-compressed-tar
+EOF
+# test x"$local" = xtrue && echo 'server.bind = "127.0.0.1"' >> "$conf"
+}
+
+
script='
s#^(my|our) \$projectroot =.*#$1 \$projectroot = "'$(dirname "$fqgitdir")'";#;
s#(my|our) \$gitbin =.*#$1 \$gitbin = "'$GIT_EXEC_PATH'";#;
@@ -344,6 +389,9 @@ case "$httpd" in
webrick)
webrick_conf
;;
+*mongoose*)
+ mongoose_conf
+ ;;
*)
echo "Unknown httpd specified: $httpd"
exit 1
--
1.6.4
^ permalink raw reply related
* Re: [PATCH 1/6 (v4)] man page and technical discussion for rev-cache
From: Junio C Hamano @ 2009-08-21 7:22 UTC (permalink / raw)
To: Nick Edelen
Cc: Nicolas Pitre, Johannes Schindelin, Sam Vilain, Michael J Gruber,
Jeff King, Shawn O. Pearce, Andreas Ericsson, Christian Couder,
git@vger.kernel.org
In-Reply-To: <op.uyzwxpmbtdk399@sirnot>
"Nick Edelen" <sirnot@gmail.com> writes:
> +DESCRIPTION
> +-----------
> +The revision cache ('rev-cache') provides a mechanism for significantly
> +speeding up revision traversals. It does this by creating an efficient
> +database (cache) of commits, their related objects and topological relations.
> +Independant of packs and the object store, this database is composed of
"independent"
> +rev-cache "slices" -- each a different file storing a given segment of commit
> +history. To map commits to their respective slices, a single index file is
> +kept for the rev-cache.
> +
> +'git-rev-cache' provides a front-end for the rev-cache mechanism, intended for
> +updating and maintaining rev-cache slices in the current repository. New cache
> +slice files can be 'add'ed, to keep the cache up-to-date; individual slices can
> +be traversed; smaller slices can be 'fuse'd into a larger slice; and the
> +rev-cache index can be regenerated.
What is the practical use of traversing a single individual slice?
> +COMMANDS
> +--------
> +
> +add
> +~~~
> +Add revisions to the cache by creating a new cache slice. Reads a revision
> +list from the command line, formatted as: `START START ... \--not END END ...`
> +
> +Options:
> +
> +\--all::
> + Include all refs in the new cache slice, like the \--all option in
> + 'rev-list'.
> +
> +\--fresh/\--incremental::
> + Exclude everything already in the revision cache, analogous to
> + \--incremental in 'pack-objects'.
Write these on separate lines, like this:
--fresh::
--incremental::
Exclude ...
> +\--stdin::
> + Read newline-seperated revisions from the standard input. Use \--not
> + to exclude commits, as on the command line.
> +
> +\--legs::
> + Ensure newly-generated cache slice has no partial ends. This means that
> + no commit has partially cached parents, in that all its parents are
> + cached or none of them are. 99.9% of users can ignore this command.
Bad presentation. I am sure 99.9% of readers would not understand what
you are talking about, and I am sure I am among them.
A "partial end" is an unexplained and undefined term at this point, and
you use it to explain what --legs is about in the first sentence. This
results in giving _no_ information to the reader with the first sentence.
Then, the second sentence , by starting with "This means that", attempts
to define the unexplained term "partial end" by rephrasing it differently.
Such a presentation structure is good only if
1. the rephrased explanation ("all or none of the parents are cached")
is much more understandable the new unfamiliar term ("partial end");
2. the new unfamiliar term is much concise; and
3. the new unfamiliar term is used repeatedly in other parts of the
documentation.
But the explanation of --legs does not satisfy any of the above three. It
is not clear what it means for a commit to get its parents "cached"; the
rephasing explanation is not much longer than the "partial end", and you
do not use "partial ends" in order to further explain other things
anywhere in the documentation.
In such a case, you are better off dropping the first cryptic "has no
partial ends" together with "This means" and introduce the concept you are
introducing more directly. And because you would be dropping the latter
half of the first sentence and "This means that", you can do this with
longer and easier to understand explanation. Perhaps...
--legs::
Make sure each and every commit in the created cache slice
either has its all parents in the same slice, or none of
its parents in it.
I said "in the _same_ slice" in my version, but I do not know if that is
what you meant by "cached". Maybe you meant "in _some_ slice" instead.
That is the kind of clarification you can afford to make, once you stop
introducing otherwise unused term like "partial ends" here.
Also, I do not find the word "legs" particularly "click" with the "no
partial ends" concept you are trying to define. It often is good to use a
verb that can be made into adjective for things like this. How about
calling this "--close"?
Close the newly created cache slice. i.e. make sure that each and
every commit in the slice has its all parents in the same slice,
or none of its parents in it.
Then later you could use "a closed slice" (vs "an open slice"), if the
distinction between a slice that was created with --legs and without
becomes useful.
> +walk
> +~~~~
> +Analogous to a slice-oriented 'rev-list', 'walk' will traverse a region in a
> +particular cache slice. Interesting and uninteresting (delimited, as with
> +'rev-list', with \--not) are specified on the command line, and output is the
> +same as vanilla 'rev-list'.
> +
> +Options:
> +
> +\--objects::
> + Like 'rev-list', 'walk' will normally only list commits. Use this
> + option to list non-commit objects as well, if they are present in the
> + cache slice.
> +
> +Output:
> +
> +'walk' will simply dump the contents of the output commit list, work list, and
> +pending object array. The headers are outputed on `stderr`, the object hashes
> +and names on `stdout`.
What is the practical use of traversing a single individual slice? For
example, if you have a slice created by an earlier 'add' that was run
with, say, v1.6.0..v1.6.1 as the parameter (so presumably it will know
only about the commits and their associated objects between these
versions), and you tell the command to 'walk' v1.0.0..v1.3.0 on the slice,
what happens?
What I am getting at is if this command is also mainly intended for
debugging this command, just like --no-objects option above.
> +fuse
> +~~~~
> +Merge several cache slices into a single large slice, like 'repack' for
> +'rev-cache'. On each invocation of 'add' a new file ("slice") is added to the
At this point, the reader has already read the explanation of what a slice
is, so it is easier to read if you said "... a new slice is added to the ..."
here, without using ambiguous but more familiar word "file".
> +Running 'fuse' every once in a while will solve this problem by coalescing all
> +the cache slices into one larger slice. For very large projects, using
> +\--ignore-size is advisable to prevent overly large cache slices. Setting git
> +'config' option 'gc.revcache' to 1 will enable cache slice fusion upon garbage
> +collection.
I am still unhappy with the word "--ignore-size". Its the threashold,
existing slices larger than which will be kept uncoalesced; the option is
not about "ignoring" the size, but means entirely opposite. The command
actively pays attention to the size while operating under this option.
Perhaps --keep-size might be slightly more appropriate; even though "size"
does not tell if it is a lower bound or upper bound, at least it makes it
clear that it is about keeping them from getting collapsed.
> +Note that 'fuse' uses the internal revision walker, so the options used in
Internal to what? Internal to git? Internal to rev-cache creator?
Internal to the fuze command implementation (and if so, why)?
> +This command prints the SHA-1 of the new slice on `stdout`, and information
> +about its work on `stderr` -- specifically which files it's removing.
When talking about the "standard output" in general terms, I'd prefer
spelling it out, reserving `stdout` as a precise technical term to refer
to the standard output stream from programming environments used only when
discussing actually programming naming the stream with that particular
spelling.
> +index
> +~~~~~
> +Regenerate the revision cache index. If the rev-cache index file associating
> +objects with cache slices gets corrupted, lost, or otherwise becomes unusable,
> +'index' will quickly regenerate the file. It's most likely that this won't be
> +needed in every day use, as it is targeted towards debugging and development.
Perhaps "reindex"?
> +alt
> +~~~
> +Create a cache slice pointer to another slice, identified by its full path:
> +`fuse path/to/other/slice`
> +
> +This command is useful if you have several repositories sharing a common
> +history. Although space requirements for rev-cache are slim anyway, you can in
> +this situation reduce it further by using slice pointers, pointing to relavant
> +slices in other repositories. Note that only one level of redirection is
> +allowed, and the slice pointer will break if the original slice is removed.
Hmm, why is this inconsistency? I think other symbolic-link-like
construct we have follow 5 levels or so...
How would you break the dependency once you make your rev-cache dependent
on another?
> diff --git a/Documentation/technical/rev-cache.txt b/Documentation/technical/rev-cache.txt
> new file mode 100644
> index 0000000..91fce8b
> --- /dev/null
> +++ b/Documentation/technical/rev-cache.txt
> @@ -0,0 +1,634 @@
> +rev-cache
> +=========
> +
> +The revision cache API ('rev-cache') provides a method for efficiently storing
> +and accessing commit branch sections. Such branch slices are defined by a
> +series of start/top (interesting) and end/bottom (uninteresting) commits. Each
It is often necessary to list synonyms like "start/top (interesting)" in
description when a concept has been widely used before being formalized
and different people used different words to refer to the same concept.
But here you are introducing the rev-cache and its related concepts for
the first time. You don't have to give three words to each of these two
concepts from the beginning. Instead, pick one unambiguous pair and stick
to them everywhere, in the code, in the input/output to/from the commands,
and in the documentation.
If it is important to be able to distinguish "uninteresting"-ness used by
rev-list and "bottom"-ness used by rev-cache, then I would suggest to use
"top/bottom". Otherwise, I would suggest "interesting/uninteresting".
^ permalink raw reply
* Re: [PATCH] Add support for the Mongoose web server.
From: Junio C Hamano @ 2009-08-21 7:49 UTC (permalink / raw)
To: Wilhansen Li; +Cc: git
In-Reply-To: <bc9549a50908202339h61525d3fo23199313cabe25e5@mail.gmail.com>
Thanks.
You would need to also update Documentation/git-instaweb.txt. Grep for
"lighttpd" or "webrick" to find where you would want to add mention of
their new friend.
^ permalink raw reply
* Re: [RFC PATCH v4 00/19] Sparse checkout
From: Junio C Hamano @ 2009-08-21 7:50 UTC (permalink / raw)
To: Nguyễn Thái Ngọc Duy; +Cc: git
In-Reply-To: <1250776033-12395-1-git-send-email-pclouds@gmail.com>
Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes:
> The recent assume-unchanged "breakage" that lets Git overwrite
> assume-unchanged files worried me. I sat back, checked and wrote tests
Yeah, it worries me, too. Does the fix to make sure the sparse stuff
won't be broken apply equally to assume-unchanged? Does the series have
such fixes to assume-unchanged bit as well?
By the way, I think the first patch in the earlier series, 540e694
(Prevent diff machinery from examining assume-unchanged entries on
worktree, 2009-08-11), is a good change regardless of the sparse
implementation, and I'm inclined to say that we should merge that part
(and I suspect there will be similar fixes to really ignore differences to
CE_VALID entries) first and then queue this new series on top.
^ permalink raw reply
* Re: [PATCH v2 5/9] revert: libify pick
From: Junio C Hamano @ 2009-08-21 7:50 UTC (permalink / raw)
To: Christian Couder
Cc: Junio C Hamano, git, Johannes Schindelin, Stephan Beyer,
Daniel Barkalow, Jakub Narebski
In-Reply-To: <20090821055001.3726.15854.chriscool@tuxfamily.org>
Christian Couder <chriscool@tuxfamily.org> writes:
> From: Stephan Beyer <s-beyer@gmx.net>
>
> This commit is made of code from the sequencer GSoC project:
>
> git://repo.or.cz/git/sbeyer.git
>
> (commit 5a78908b70ceb5a4ea9fd4b82f07ceba1f019079)
>
> The goal of this commit is to abstract out pick functionnality
> into a new pick() function made of code from "builtin-revert.c".
>
> The new pick() function is in a new "pick.c" file with an
> associated "pick.h".
Is it pick() or pick_commit()?
By the way, this comment applies to other messages in the series, but do
these original commits by Stephan lack any meaningful messages? I would
actually have expected to see a commit log message that looks more like:
From: Stephan Beyer <...>
Meaningful log message Stephan describes what this commit does in
sufficient detail, perhaps with clarification and rewording by
Christian.
Second and subsequent paragraph to explain it as necessary.
[cc: this is based on 5a78908b70ceb5a4ea9fd4b82f07ceba1f019079
from Stephan's git://repo.or.cz/git/sbeyer.git]
Signed-off-by: ...
The point is that the "origin info" would be a side-note, not the first
and the most important thing in the message.
^ permalink raw reply
* [PATCH] Make test number t7406- unique
From: Johannes Sixt @ 2009-08-21 8:32 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Git Mailing List
From: Johannes Sixt <j6t@kdbg.org>
We skip t7407 because a patch series is cooking that uses is.
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
---
...e-reference.sh => t7408-submodule-reference.sh} | 0
1 files changed, 0 insertions(+), 0 deletions(-)
rename t/{t7406-submodule-reference.sh => t7408-submodule-reference.sh} (100%)
diff --git a/t/t7406-submodule-reference.sh b/t/t7408-submodule-reference.sh
similarity index 100%
rename from t/t7406-submodule-reference.sh
rename to t/t7408-submodule-reference.sh
--
1.6.4.204.g6aad7
^ permalink raw reply
* Re: [PATCH] Make test number t7406- unique
From: Johan Herland @ 2009-08-21 8:50 UTC (permalink / raw)
To: git; +Cc: Johannes Sixt, Junio C Hamano
In-Reply-To: <4A8E5B99.3080705@viscovery.net>
On Friday 21 August 2009, Johannes Sixt wrote:
> We skip t7407 because a patch series is cooking that uses is.
Alternatively, you could reuse t7404 which is not used (in my checkout at
least). E.g.:
mv t7405-submodule-merge.sh t7404-submodule-merge.sh
mv t7406-submodule-reference.sh t7405-submodule-reference.sh
Have fun! :)
...Johan
--
Johan Herland, <johan@herland.net>
www.herland.net
^ permalink raw reply
* [PATCH 2/2 (v3)] reset: make the output more user-friendly.
From: Matthieu Moy @ 2009-08-21 8:57 UTC (permalink / raw)
To: git, gitster; +Cc: Matthieu Moy
In-Reply-To: <1250845079-30614-1-git-send-email-Matthieu.Moy@imag.fr>
git reset without argument displays a summary of the remaining
unstaged changes. The problem with these is that they look like an
error message, and the format is inconsistant with the format used in
other places like "git diff --name-status".
This patch mimics the output of "git diff --name-status", and adds a
header to make it clear the output is informative, and not an error.
It also changes the output of "git add --refresh --verbose" in the same
way.
Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>
---
In previous version, I hadn't noticed that the same message was
displayed for 'git reset' and for 'git add --refresh --verbose'. This
new version takes both cases into account, and avoids saying "after
reset" when the user called "add".
builtin-add.c | 2 +-
builtin-reset.c | 3 ++-
cache.h | 4 ++--
read-cache.c | 26 ++++++++++++++++++++------
t/t7102-reset.sh | 3 ++-
5 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/builtin-add.c b/builtin-add.c
index a325bc9..006fd08 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -106,7 +106,7 @@ static void refresh(int verbose, const char **pathspec)
/* nothing */;
seen = xcalloc(specs, 1);
refresh_index(&the_index, verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET,
- pathspec, seen);
+ pathspec, seen, "Unstaged changes after refreshing the index:");
for (i = 0; i < specs; i++) {
if (!seen[i])
die("pathspec '%s' did not match any files", pathspec[i]);
diff --git a/builtin-reset.c b/builtin-reset.c
index ddf68d5..0fc0b07 100644
--- a/builtin-reset.c
+++ b/builtin-reset.c
@@ -108,7 +108,8 @@ static int update_index_refresh(int fd, struct lock_file *index_lock, int flags)
if (read_cache() < 0)
return error("Could not read index");
- result = refresh_cache(flags) ? 1 : 0;
+ result = refresh_index(&the_index, (flags), NULL, NULL,
+ "Unstaged changes after reset:") ? 1 : 0;
if (write_cache(fd, active_cache, active_nr) ||
commit_locked_index(index_lock))
return error ("Could not refresh index");
diff --git a/cache.h b/cache.h
index ae0e83e..fda9816 100644
--- a/cache.h
+++ b/cache.h
@@ -330,7 +330,7 @@ static inline void remove_name_hash(struct cache_entry *ce)
#define remove_file_from_cache(path) remove_file_from_index(&the_index, (path))
#define add_to_cache(path, st, flags) add_to_index(&the_index, (path), (st), (flags))
#define add_file_to_cache(path, flags) add_file_to_index(&the_index, (path), (flags))
-#define refresh_cache(flags) refresh_index(&the_index, (flags), NULL, NULL)
+#define refresh_cache(flags) refresh_index(&the_index, (flags), NULL, NULL, NULL)
#define ce_match_stat(ce, st, options) ie_match_stat(&the_index, (ce), (st), (options))
#define ce_modified(ce, st, options) ie_modified(&the_index, (ce), (st), (options))
#define cache_name_exists(name, namelen, igncase) index_name_exists(&the_index, (name), (namelen), (igncase))
@@ -477,7 +477,7 @@ extern int check_path(const char *path, int len, struct stat *st);
#define REFRESH_IGNORE_MISSING 0x0008 /* ignore non-existent */
#define REFRESH_IGNORE_SUBMODULES 0x0010 /* ignore submodules */
#define REFRESH_IN_PORCELAIN 0x0020 /* user friendly output, not "needs update" */
-extern int refresh_index(struct index_state *, unsigned int flags, const char **pathspec, char *seen);
+extern int refresh_index(struct index_state *, unsigned int flags, const char **pathspec, char *seen, char *header_msg);
struct lock_file {
struct lock_file *next;
diff --git a/read-cache.c b/read-cache.c
index f1aff81..1bbaf1c 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -1065,7 +1065,18 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate,
return updated;
}
-int refresh_index(struct index_state *istate, unsigned int flags, const char **pathspec, char *seen)
+static void show_file(const char * fmt, const char * name, int in_porcelain,
+ int * first, char *header_msg)
+{
+ if (in_porcelain && *first && header_msg) {
+ printf("%s\n", header_msg);
+ *first=0;
+ }
+ printf(fmt, name);
+}
+
+int refresh_index(struct index_state *istate, unsigned int flags, const char **pathspec,
+ char *seen, char *header_msg)
{
int i;
int has_errors = 0;
@@ -1074,11 +1085,14 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
int quiet = (flags & REFRESH_QUIET) != 0;
int not_new = (flags & REFRESH_IGNORE_MISSING) != 0;
int ignore_submodules = (flags & REFRESH_IGNORE_SUBMODULES) != 0;
+ int first = 1;
+ int in_porcelain = (flags & REFRESH_IN_PORCELAIN);
unsigned int options = really ? CE_MATCH_IGNORE_VALID : 0;
- const char *needs_update_message;
+ const char *needs_update_fmt;
+ const char *needs_merge_fmt;
- needs_update_message = ((flags & REFRESH_IN_PORCELAIN)
- ? "locally modified" : "needs update");
+ needs_update_fmt = (in_porcelain ? "M\t%s\n" : "%s: needs update\n");
+ needs_merge_fmt = (in_porcelain ? "U\t%s\n" : "%s: needs merge\n");
for (i = 0; i < istate->cache_nr; i++) {
struct cache_entry *ce, *new;
int cache_errno = 0;
@@ -1094,7 +1108,7 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
i--;
if (allow_unmerged)
continue;
- printf("%s: needs merge\n", ce->name);
+ show_file(needs_merge_fmt, ce->name, in_porcelain, &first, header_msg);
has_errors = 1;
continue;
}
@@ -1117,7 +1131,7 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
}
if (quiet)
continue;
- printf("%s: %s\n", ce->name, needs_update_message);
+ show_file(needs_update_fmt, ce->name, in_porcelain, &first, header_msg);
has_errors = 1;
continue;
}
diff --git a/t/t7102-reset.sh b/t/t7102-reset.sh
index e637c7d..e85ff02 100755
--- a/t/t7102-reset.sh
+++ b/t/t7102-reset.sh
@@ -419,7 +419,8 @@ test_expect_success 'resetting an unmodified path is a no-op' '
'
cat > expect << EOF
-file2: locally modified
+Unstaged changes after reset:
+M file2
EOF
test_expect_success '--mixed refreshes the index' '
--
1.6.4.187.gd399.dirty
^ permalink raw reply related
* [PATCH 1/2] Rename REFRESH_SAY_CHANGED to REFRESH_IN_PORCELAIN.
From: Matthieu Moy @ 2009-08-21 8:57 UTC (permalink / raw)
To: git, gitster; +Cc: Matthieu Moy
In-Reply-To: <vpqljlipcs6.fsf@bauges.imag.fr>
The change in the output is going to become more general than just saying
"changed", so let's make the variable name more general too.
Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>
---
builtin-add.c | 2 +-
builtin-reset.c | 4 ++--
cache.h | 2 +-
read-cache.c | 2 +-
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/builtin-add.c b/builtin-add.c
index 581a2a1..a325bc9 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -105,7 +105,7 @@ static void refresh(int verbose, const char **pathspec)
for (specs = 0; pathspec[specs]; specs++)
/* nothing */;
seen = xcalloc(specs, 1);
- refresh_index(&the_index, verbose ? REFRESH_SAY_CHANGED : REFRESH_QUIET,
+ refresh_index(&the_index, verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET,
pathspec, seen);
for (i = 0; i < specs; i++) {
if (!seen[i])
diff --git a/builtin-reset.c b/builtin-reset.c
index 5fa1789..ddf68d5 100644
--- a/builtin-reset.c
+++ b/builtin-reset.c
@@ -261,7 +261,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
die("Cannot do %s reset with paths.",
reset_type_names[reset_type]);
return read_from_tree(prefix, argv + i, sha1,
- quiet ? REFRESH_QUIET : REFRESH_SAY_CHANGED);
+ quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN);
}
if (reset_type == NONE)
reset_type = MIXED; /* by default */
@@ -302,7 +302,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
break;
case MIXED: /* Report what has not been updated. */
update_index_refresh(0, NULL,
- quiet ? REFRESH_QUIET : REFRESH_SAY_CHANGED);
+ quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN);
break;
}
diff --git a/cache.h b/cache.h
index 9222774..ae0e83e 100644
--- a/cache.h
+++ b/cache.h
@@ -476,7 +476,7 @@ extern int check_path(const char *path, int len, struct stat *st);
#define REFRESH_QUIET 0x0004 /* be quiet about it */
#define REFRESH_IGNORE_MISSING 0x0008 /* ignore non-existent */
#define REFRESH_IGNORE_SUBMODULES 0x0010 /* ignore submodules */
-#define REFRESH_SAY_CHANGED 0x0020 /* say "changed" not "needs update" */
+#define REFRESH_IN_PORCELAIN 0x0020 /* user friendly output, not "needs update" */
extern int refresh_index(struct index_state *, unsigned int flags, const char **pathspec, char *seen);
struct lock_file {
diff --git a/read-cache.c b/read-cache.c
index 4e3e272..f1aff81 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -1077,7 +1077,7 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
unsigned int options = really ? CE_MATCH_IGNORE_VALID : 0;
const char *needs_update_message;
- needs_update_message = ((flags & REFRESH_SAY_CHANGED)
+ needs_update_message = ((flags & REFRESH_IN_PORCELAIN)
? "locally modified" : "needs update");
for (i = 0; i < istate->cache_nr; i++) {
struct cache_entry *ce, *new;
--
1.6.4.187.gd399.dirty
^ permalink raw reply related
* Re: What's cooking in git.git (Aug 2009, #03; Thu, 20)
From: Paolo Bonzini @ 2009-08-21 9:10 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7veir5naq3.fsf@alter.siamese.dyndns.org>
On 08/21/2009 04:48 AM, Junio C Hamano wrote:
> Has been ejected from 'pu' for some time, expecting a reroll.
I've been trying for a while to have push refspecs and tracking working
together, but haven't come with anything that I like.
I'll let it sleep for a while so that I can look at the problem again
with a fresh mind when I come back to it.
Paolo
^ permalink raw reply
* Re: [RFC PATCH v4 00/19] Sparse checkout
From: Nguyen Thai Ngoc Duy @ 2009-08-21 9:15 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vprapip1v.fsf@alter.siamese.dyndns.org>
2009/8/21 Junio C Hamano <gitster@pobox.com>:
> Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes:
>
>> The recent assume-unchanged "breakage" that lets Git overwrite
>> assume-unchanged files worried me. I sat back, checked and wrote tests
>
> Yeah, it worries me, too. Does the fix to make sure the sparse stuff
> won't be broken apply equally to assume-unchanged? Does the series have
> such fixes to assume-unchanged bit as well?
This series does not fix assume-unchanged bit. I'd like to focus on
skip-worktree bit now. I still need to write a few more tests for
git-apply, git-checkout... but I think they are safe. It's up to you
to see if changes apply to assume-unchanged bit, in patches 4/19 and
5/19. I don't know if I understand assume-unchanged semantics
correctly anymore :-)
Anyway I think we could put a big fat warning above ce_uptodate()
macro definition, saying that this bit/macro could be faked by
assume-unchanged or skip-worktree bit, so don't rely on that macro
when it comes to writing (at least for skip-worktree part).
Hmm.. _or_ we could make it clear whether it is truly uptodate, or
faked uptodate. Some code path will be updated to only trust "truly
uptodate" bit, which is clearer and easier to grasp than messy logics
like "if (ce_uptodate(ce) && !ce_skip_worktree(ce))". Something like
this as a starting point (for demonstration only, I don't think it
compiles)
diff --git a/cache.h b/cache.h
index a401daf..05fb746 100644
--- a/cache.h
+++ b/cache.h
@@ -179,6 +179,7 @@ struct cache_entry {
/* Only remove in work directory, not index */
#define CE_WT_REMOVE (0x400000)
+#define CE_ASSUME_UPTODATE (0x800000)
/*
* Extended on-disk flags
@@ -236,9 +237,11 @@ static inline size_t ce_namelen(const struct
cache_entry *ce)
ondisk_cache_entry_extended_size(ce_namelen(ce)) : \
ondisk_cache_entry_size(ce_namelen(ce)))
#define ce_stage(ce) ((CE_STAGEMASK & (ce)->ce_flags) >> CE_STAGESHIFT)
-#define ce_uptodate(ce) ((ce)->ce_flags & CE_UPTODATE)
+#define ce_truely_uptodate(ce) ((ce)->ce_flags & CE_UPTODATE)
+#define ce_uptodate(ce) ((ce)->ce_flags & (CE_UPTODATE | CE_ASSUME_UPTODATE))
#define ce_skip_worktree(ce) ((ce)->ce_flags & CE_SKIP_WORKTREE)
#define ce_mark_uptodate(ce) ((ce)->ce_flags |= CE_UPTODATE)
+#define ce_mark_assume_uptodate(ce) ((ce)->ce_flags |= CE_ASSUME_UPTODATE)
#define ce_permissions(mode) (((mode) & 0100) ? 0755 : 0644)
static inline unsigned int create_ce_mode(unsigned int mode)
diff --git a/read-cache.c b/read-cache.c
index 5ee7d9d..c022955 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -1005,7 +1005,7 @@ static struct cache_entry
*refresh_cache_ent(struct index_state *istate,
return ce;
if (!ignore_valid && ((ce->ce_flags & CE_VALID) || ce_skip_worktree(ce))) {
- ce_mark_uptodate(ce);
+ ce_mark_assume_uptodate(ce);
return ce;
}
Still thinking of it. Seems like a good change...
> By the way, I think the first patch in the earlier series, 540e694
> (Prevent diff machinery from examining assume-unchanged entries on
> worktree, 2009-08-11), is a good change regardless of the sparse
> implementation, and I'm inclined to say that we should merge that part
> (and I suspect there will be similar fixes to really ignore differences to
> CE_VALID entries) first and then queue this new series on top.
I have no problem with that.
--
Duy
^ permalink raw reply related
* Re: [RFC PATCH v4 04/19] Teach Git to respect skip-worktree bit (reading part)
From: Nguyen Thai Ngoc Duy @ 2009-08-21 9:19 UTC (permalink / raw)
To: git
In-Reply-To: <1250776033-12395-5-git-send-email-pclouds@gmail.com>
2009/8/20 Nguyễn Thái Ngọc Duy <pclouds@gmail.com>:
> grep: turn on --cached for files that is marked skip-worktree
> ls-files: do not check for deleted file that is marked skip-worktree
> update-index: ignore update request if it's skip-worktree, while still allows removing
> diff*: skip worktree version
I kept reminding myself and still managed to miss it. skip-worktree
bit is not completely independent from assume-unchanged. It shares
CE_MATCH_IGNORE_VALID flag in ie_match_stat(). Should have mentioned
that in commit log.
--
Duy
^ permalink raw reply
* [PATCH] test suite: add a check that all test numbers are unique
From: Johannes Sixt @ 2009-08-21 9:28 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Git Mailing List
From: Johannes Sixt <j6t@kdbg.org>
The test runs only if 'make all' is used. Its purpose is to alert our
valued integrator if different branches are merged that happen to
introduce the same test number.
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
---
t/Makefile | 1 +
t/check_unique_numbers.sh | 27 +++++++++++++++++++++++++++
2 files changed, 28 insertions(+), 0 deletions(-)
create mode 100755 t/check_unique_numbers.sh
diff --git a/t/Makefile b/t/Makefile
index bd09390..2a451b7 100644
--- a/t/Makefile
+++ b/t/Makefile
@@ -17,6 +17,7 @@ T = $(wildcard t[0-9][0-9][0-9][0-9]-*.sh)
TSVN = $(wildcard t91[0-9][0-9]-*.sh)
all: pre-clean
+ '$(SHELL_PATH_SQ)' ./check_unique_numbers.sh
$(MAKE) aggregate-results-and-cleanup
$(T):
diff --git a/t/check_unique_numbers.sh b/t/check_unique_numbers.sh
new file mode 100755
index 0000000..e767275
--- /dev/null
+++ b/t/check_unique_numbers.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# checks whether test case numbers are unique;
+# returns non-zero if any duplicates were found
+
+check_numbers () {
+ last= dup=
+ while read name
+ do
+ case $name in
+ t[0-9][0-9][0-9][0-9]-*.sh)
+ number=${name%%-*}
+ if test "$number" = "$last"; then
+ dup="$dup $number"
+ fi
+ last=$number
+ ;;
+ esac
+ done
+ test -z "$dup" || {
+ echo >&2 "error: duplicate test numbers:" $dup
+ return 1
+ }
+}
+
+ls -1 | # no wildcard to avoid overflow of command line
+check_numbers
--
1.6.4.204.g6aad7
^ permalink raw reply related
* Rebase with filters
From: Nigel Magnay @ 2009-08-21 9:41 UTC (permalink / raw)
To: Git ML
Hello. I seem to be doing something wrong - that has previously caused
me to loose data (well, not really, the commit was still there, but it
took me a while to notice - gotta love the non-destructive nature of
git)
I have a project that contains a file that, irritatingly, an IDE will
always re-format on save, even if there are no changes. So, I use a
clean and smudge filter to re-order it into a sane format that's
easier to detect if there have actually been changes.
So far, so good. But, not everyone always uses this filter, and I get
some unexpected behavior when doing a 'git rebase'. For example - the
repository starts with a commit that has been sanely-ordered. I make a
change of several files, and commit locally - but when I come to push,
I find that origin/master has moved.
No worries, I do
git fetch
git rebase origin/master
Now I see the usual text going past, and including:
....
error: realtime/modules/realtime-flex-components/.flexLibProperties:
does not match index
Using index info to reconstruct a base tree...
<stdin>:59: trailing whitespace.
<stdin>:81: trailing whitespace.
<stdin>:83: trailing whitespace.
parameters:[
<stdin>:98: space before tab in indent.
if (item.value == null )
<stdin>:99: space before tab in indent.
{
warning: squelched 214 whitespace errors
warning: 219 lines add whitespace errors.
Falling back to patching base and 3-way merge...
error: Entry 'realtime/modules/realtime-flex-components/.flexLibProperties'
not uptodate. Cannot merge.
fatal: merging of trees 85b26f7c165c2a9d362340187b79527428b650e8 and
3ab3078b55e17dcb1f3f4c8e6a65eff517eedb92 failed
Failed to merge in the changes.
Patch failed at 0001 More KPI/Report work
When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To restore the original branch and stop rebasing run "git rebase --abort".
OK - looking a bit closer, someone committed .flexLibProperties
without the filter. I guess that's the "does not match index". Let's
merge..
(|REBASE) $ git mergetool
No files need merging
Interesting - I guess there were no conflicts when the filtering was
all done. Let's just look at the status..
(|REBASE) $ git status
# Not currently on any branch.
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: realtime/modules/realtime-flex-components/.flexLibProperties
Eek... Where's the rest of my files?!
My guess is that the "error" reported further up ought to terminate
the rebase without giving me the "When you have resolved this problem
run "git rebase --continue" because otherwise I end up loosing the
majority of the changes in my rebased commit.. ?
^ permalink raw reply
* Re: Continue git clone after interruption
From: Jakub Narebski @ 2009-08-21 10:07 UTC (permalink / raw)
To: Nicolas Pitre; +Cc: Tomasz Kontusz, git, Johannes Schindelin, Scott Chacon
In-Reply-To: <alpine.LFD.2.00.0908201358010.6044@xanadu.home>
On Thu, 20 Aug 2009, Nicolas Pitre wrote:
> On Thu, 20 Aug 2009, Jakub Narebski wrote:
>> On Wed, 19 Aug 2009, Nicolas Pitre wrote:
>>> You'll get the very latest revision for HEAD, and only that. The size
>>> of the transfer will be roughly the size of a daily snapshot, except it
>>> is fully up to date. It is however non resumable in the event of a
>>> network outage. My proposal is to replace this with a "git archive"
>>> call. It won't get all branches, but for the purpose of initialising
>>> one's repository that should be good enough. And the "git archive" can
>>> be fully resumable as I explained.
>>
>> It is however only 2.5 MB out of 37 MB that are resumable, which is 7%
>> (well, that of course depends on repository). Not that much that is
>> resumable.
>
> Take the Linux kernel then. It is more like 75 MB.
Ah... good example.
On the other hand Linux is fairly large project in terms of LoC, but
it had its history cut when moving to Git, so the ratio of git-archive
of HEAD to the size of packfile is overemphasized here.
>>> Now to deepen that history. Let's say you want 10 more revisions going
>>> back then you simply perform the fetch again with a --depth=10. Right
>>> now it doesn't seem to work optimally, but the pack that is then being
>>> sent could be made of deltas against objects found in the commits we
>>> already have. Currently it seems that a pack that also includes those
>>> objects we already have in addition to those we want is created, which
>>> is IMHO a flaw in the shallow support that shouldn't be too hard to fix.
>>> Each level of deepening should then be as small as standard fetches
>>> going forward when updating the repository with new revisions.
>>
>> You would have the same (or at least quite similar) problems with
>> deepening part (the 'incrementals' transfer part) as you found with my
>> first proposal of server bisection / division of rev-list, and serving
>> 1/Nth of revisions (where N is selected so packfile is reasonable) to
>> client as incrementals. Yours is top-down, mine was bottom-up approach
>> to sending series of smaller packs. The problem is how to select size
>> of incrementals, and that incrementals are all-or-nothing (but see also
>> comment below).
>
> Yes and no. Combined with a slight reordering of commit objects, it
> could be possible to receive a partial pack and still be able to extract
> a bunch of full revisions. The biggest issue is to be able to transfer
> revision x (75 MB for Linux), but revision x-1 usually requires only a
> few kilobytes, revision x-2 a few other kilobytes, etc. Remember that
> you are likely to have only a few deltas from one revision to another,
> which is not the case for the very first revision you get.
Let's reiterate again, to be sure that I understand this correctly:
You make use here of a few facts:
1. Objects in packfile are _usually_ sorted in recency order, with most
recent commits, and most recent versions of trees and tags being in
the front of pack file, and being base objects for a large set of
objects. Note the "usually" part; it is not set in stone as for RCS
(and CVS) reverse delta based repository format.
2. There is support in git pack format to do 'deepening' of shallow
clone, which means that git can generate incrementals in top-down
order, _similar to how objects are ordered in packfile_.
3. git-archive output is stable. _git-archive can be made resumable_
(with range/partial requests), and can be made so it can create
single-head depth 0 shallow clone.
Also, with top-down deepening order even if you don't use
'git clone --continue' but 'git clone --skip' (or something), you
would have got usable shallow clone. In the most extreme case when
you are able to get only the fully resumable part, i.e. git-archive
part (with top commit), you would have single-branch depth 0
shallow clone (not very usable, but still better than nothing).
> A special
> mode to pack-object could place commit objects only after all the
> objects needed to create that revision. So once you get a commit object
> on the receiving end, you could assume that all objects reachable from
> that commit are already received, or you had them locally already.
Yes, with such mode (which I think wouldn't reduce / interfere with
ability for upload-pack to pack more tightly by reordering objects
and choosing different deltas) it would be easy to do a salvage of
a partially completed / transferred packfile. Even if there is no
extension to tell git server which objects we have ("have" is only
about commits), if there is at least one commit object in received
part of packfile, we can try to continue from later (from more);
there is less left to download.
>
>> In proposal using git-archive and shallow clone deepening as incrementals
>> you have this small seed (how small it depends on repository: 50% - 5%)
>> which is resumable. And presumably with deepening you can somehow make
>> some use from incomplete packfile, only part of which was transferred
>> before network error / disconnect. And even tell server about objects
>> which you managed to extract from *.pack.part.
>
> yes. And at that point resuming the transfer is just another case of
> shallow repository deepening.
Also for deepening top-down incrementals like in your proposal you can
have 'salvage' operation which tries to use something out of partially
transferred packfile (partially downloaded incremental). It is not,
I think, the case with my earlier 'server bisect' bottom-up incrementals
idea.
>
>> *NEW IDEA*
>>
>> Another solution would be to try to come up with some sort of stable
>> sorting of objects so that packfile generated for the same parameters
>> (endpoints) would be always byte-for-byte the same. But that might be
>> difficult, or even impossible.
>
> And I don't want to commit to that either. Having some flexibility in
> object ordering makes it possible to improve on the packing heuristics.
> We certainly should avoid imposing strong restrictions like that for
> little gain. Even the deltas are likely to be different from one
> request to another when using threads as one thread might be getting
> more CPU time than another slightly modifying the outcome.
Right.
>> Well, we could send the list of objects in pack in order used later by
>> pack creation to client (non-resumable but small part), and if packfile
>> transport was interrupted in the middle client would compare list of
>> complete objects in part of packfile against this manifest, and sent
>> request to server with *sorted* list of object it doesn't have yet.
>
> Well... actually that's one of the item for pack V4. Lots of SHA1s are
> duplicated in tree and commit objects, in addition to the pack index
> file. With pack v4 all those SHA1s would be stored only once in a table
> and objects would index that table instead.
>
> Still, that is not _that_ small though. Just look at the size of the
> pack index file for the Linux repository to give you an idea.
Well, as such plan (map) of a packfile wouldn't be much smaller than
pack index, if pack index file is large enough (or connection crappy
enough) that it couldn't be transferred without interruption.
Nevertheless 34 MB index for largest 310 MB packfile in Linux kernel
http://www.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git/objects/pack/
isn't something very large. And objects-list / plan of packfile would
be of comparable size.
I was envisioning packfile plan (packfile map) as something like that
sha1 TERMINATOR
for objects that are not deltified in the packfile, and
sha1 SEPARATOR base-sha1 TERMINATOR
for objects that are deltified (or something like that; we could use
pkt-line format instead).
>> Server would probably have to check validity of objects list first (the
>> object list might be needed to be more than just object list; it might
>> need to specify topology of deltas, i.e. which objects are base for which
>> ones). Then it would generate rest of packfile.
>
> I'm afraid that has the looks of something adding lots of complexity to
> a piece of git that is already quite complex already, namely
> pack-objects. And there is already only a few individuals with their
> brain around it.
Well, with complexity or server CPU/IO because one should not trust
client (unfortunately), with 'packfile plan' transfer being non-resumable,
and also with requiring packv4 or a temporary file or memory to send
packfile plan (packfile map)... I think we can scrape that half-baked
idea.
>>>> [...] I don't know enough
>>>> about 'shallow' capability (and what it enables) to know whether
>>>> it can be used for that. Can you elaborate?
>>>
>>> See above, or Documentation/technical/shallow.txt.
>>
>> Documentation/technical/shallow.txt doesn't cover "shallow", "unshallow"
>> and "deepen" commands from 'shallow' capability extension to git pack
>> protocol (http://git-scm.com/gitserver.txt).
>
> 404 Not Found
>
> Maybe that should be committed to git in Documentation/technical/ as
> well?
This was plain text RFC for the Git Packfile Protocol, generated from
rfc2629 XML sources at http://github.com/schacon/gitserver-rfc
Scott, what happened to http://git-scm.com/gitserver.txt?
And could you create 'rfc' or 'text' branch in gitserver-rfc
repository, with processed plain/text output, similar to 'man' and
'html' branches in git.git repository? TIA.
_Some_ description of pack protocol can be found in git mailing list
archives
http://thread.gmane.org/gmane.comp.version-control.git/118956
in "The Git Community Book"
http://book.git-scm.com/7_transfer_protocols.html
http://github.com/schacon/gitbook/blob/master/text/54_Transfer_Protocols/0_Transfer_Protocols.markdown
and in "Pro Git"
http://progit.org/book/ch9-6.html
http://github.com/progit/progit/blob/master/en/09-git-internals/01-chapter9.markdown
The description in Documentation/technical/pack-protocol.txt is very
brief, and Documentation/technical/shallow.txt doesn't cover 'shallow'
capability of git pack protocol.
>>>> Then you have to finish clone / fetch. All solutions so far include
>>>> some kind of incremental improvements. My first proposal of bisect
>>>> fetching 1/nth or predefined size pack is buttom-up solution, where
>>>> we build full clone from root commits up. You propose, from what
>>>> I understand build full clone from top commit down, using deepening
>>>> from shallow clone. In this step you either get full incremental
>>>> or not; downloading incremental (from what I understand) is not
>>>> resumable / they do not support partial fetch.
>>>
>>> Right. However, like I said, the incremental part should be much
>>> smaller and therefore less susceptible to network troubles.
>>
>> If you have 7% total pack size of git-archive resumable part, how small
>> do you plan to have those incremental deepening? Besides in my 1/Nth
>> proposal those bottom-up packs werealso meant to be sufficiently small
>> to avoid network troubles.
>
> Two issues here: 1) people with slow links might not be interested in a
> deep history as it costs them time. 2) Extra revisions should typically
> require only a few KB each, therefore we might manage to ask for the
> full history after the initial revision is downloaded and salvage as
> much as we can if a network outage is encountered. There is no need for
> arbitrary size, unless the user decides arbitrarily to get only 10 more
> revisions, or 100 more, etc.
Those two features of your proposal:
1.) It is possible salvage of partially transferred packfiles (so there
is no requirement to guess accurately what size should they be),
2.) After completing initial git-archive transfer, you can convert
incomplete clone into functioning repository. It would be shallow
clone, and can be missing some branches and tags, but you can work
with it if network connection fails completely.
make it very compelling.
>> P.S. As you can see implementing resumable clone isn't easy...
>
> I've been saying that all along for quite a while now. ;-)
Well, on the other hand side we have example of how long it took to
come to current implementation of git submodules. But if finally
got done.
The git-archive + deepening approach you proposed can be split into
smaller individual improvements. You don't need to implement it all
at once.
1. Improve deepening of shallow clone. This means sending only required
objects, and being able to use as a base objects that other side has
and send thin pack.
2. Add support for resuming (range request) of git-archive. It is up
to client to translate size of partial transfer of compressed file
into range request of original (uncompressed) archive.
3. Create new git-archive pseudoformat, used to transfer single commit
(with commit object and original branch name in some extended header,
similar to how commit ID is stored in extended pax header or ZIP
comment). It would imply not using export-* gitattributes.
4. Implement alternate ordering of objects in packfile, so commit object
is put immediately after all its prerequisites.
5. Implement 'salvage' operation, which given partially transferred
packfile would deepen shallow clone, or advance tracking branches,
ensuring that repository would pass fsck after this operation.
Probably requires 4; might be not possible or much harder to salvage
anything with current ordering of objects in packfile.
6. Implement resumable clone ("git clone --keep <URL> [<directory>]",
"git clone --resume" / "git clone --continue", "git clone --abort",
"git clone --make-shallow" / "git clone --salvage").
Requires 1-5.
--
Jakub Narebski
Poland
^ permalink raw reply
* Re: Continue git clone after interruption
From: Matthieu Moy @ 2009-08-21 10:26 UTC (permalink / raw)
To: Jakub Narebski
Cc: Nicolas Pitre, Tomasz Kontusz, git, Johannes Schindelin,
Scott Chacon
In-Reply-To: <200908211207.38555.jnareb@gmail.com>
Jakub Narebski <jnareb@gmail.com> writes:
> On the other hand Linux is fairly large project in terms of LoC, but
> it had its history cut when moving to Git, so the ratio of git-archive
> of HEAD to the size of packfile is overemphasized here.
Emacs can be a good example if you want a project with a loooong
history.
emacs.git$ git ll | wc -l
100651
emacs.git$ du -sh emacs.tar.gz .git/objects/pack/pack-144583582d53e273028966c6de2b3fb2fe3504bc.pack
29M emacs.tar.gz
138M .git/objects/pack/pack-144583582d53e273028966c6de2b3fb2fe3504bc.pack
(from git://git.savannah.gnu.org/emacs.git )
--
Matthieu
^ permalink raw reply
* Display bug in gitk -S
From: Martin Stjernholm @ 2009-08-21 11:46 UTC (permalink / raw)
To: git
The following applies to git 1.6.4.
I did a "git log -S" with some search term, and it filtered out seven
disconnected commits from a fairly large repository.
Then I tried "gitk -S" with the same term. In the upper pane I briefly
see the seven commits, each with a dot in a different column and a
down-pointing arrow. After a while (presumably when it has searched
through the whole repo and has discovered that the commits are
disconnected), the display is updated to include the preceding commits
as white dots. However, the total number of shown commits is still
restricted to seven, which means that I now only see the first four of
the commits I should see.
^ permalink raw reply
* Re: What's cooking in git.git (Aug 2009, #03; Thu, 20)
From: Mark A Rada @ 2009-08-21 12:40 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git
In-Reply-To: <7veir5naq3.fsf@alter.siamese.dyndns.org>
On 20-Aug-09, at 10:48 PM, Junio C Hamano wrote:
> Should graduate to 'master' soon.
>
> * mr/gitweb-xz (2009-08-06) 3 commits
> (merged to 'next' on 2009-08-14 at b63b8e6)
> + gitweb: add support for XZ compressed snapshots
> + gitweb: update INSTALL regarding specific snapshot settings
> + gitweb: support to globally disable a snapshot format
>
I never submitted any tests for the patch that adds global snapshot
disabling
functionality to gitweb.
Jakub, I changed the gitweb_run routine to capture STDOUT as well, is
that ok?
Unless I missed a case, the tests show that the extra condition check
that was
added in the &git_snapshot routine is never actually executed, because a
disabled snapshot format is not added to @snapshot_fmts, which is
checked
first.
snippet:
5178 } elsif (!grep($_ eq $format, @snapshot_fmts)) {
5179 die_error(403, "Unsupported snapshot format");
5180 } elsif ($known_snapshot_formats{$format}{'disabled'}) {
5181 die_error(403, "Snapshot format not allowed");
5182 }
5183
--
Mark A Rada (ferrous26)
marada@uwaterloo.ca
---
t/t9500-gitweb-standalone-no-errors.sh | 67 +++++++++++++++++++++++
++++++++-
1 files changed, 66 insertions(+), 1 deletions(-)
diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-
standalone-no-errors.sh
index 6275181..9ce9667 100755
--- a/t/t9500-gitweb-standalone-no-errors.sh
+++ b/t/t9500-gitweb-standalone-no-errors.sh
@@ -57,10 +57,11 @@ gitweb_run () {
# we are interested only in properly formatted errors/warnings
rm -f gitweb.log &&
perl -- "$SCRIPT_NAME" \
- >/dev/null 2>gitweb.log &&
+ >gitweb.output 2>gitweb.log &&
if grep "^[[]" gitweb.log >/dev/null 2>&1; then false; else true; fi
# gitweb.log is left for debugging
+ # gitweb.output is used to parse output
}
. ./test-lib.sh
@@ -704,4 +705,68 @@ test_expect_success \
gitweb_run "p=.git;a=summary"'
test_debug 'cat gitweb.log'
+
+#
----------------------------------------------------------------------
+# snapshot settings
+
+cat >>gitweb_config.perl <<EOF
+
+\$feature{'snapshot'}{'override'} = 0;
+EOF
+
+test_expect_success \
+ 'snapshots: tgz only default format enabled' \
+ 'gitweb_run "p=.git;a=snapshot;h=HEAD;sf=tgz" &&
+ grep "Status: 200 OK" gitweb.output &&
+ gitweb_run "p=.git;a=snapshot;h=HEAD;sf=tbz2" &&
+ grep "403 - Unsupported snapshot format" gitweb.output &&
+ gitweb_run "p=.git;a=snapshot;h=HEAD;sf=txz" &&
+ grep "403 - Unsupported snapshot format" gitweb.output &&
+ gitweb_run "p=.git;a=snapshot;h=HEAD;sf=zip" &&
+ grep "403 - Unsupported snapshot format" gitweb.output'
+test_debug 'cat gitweb.output'
+
+
+cat >>gitweb_config.perl <<EOF
+
+\$feature{'snapshot'}{'default'} = ['tgz','tbz2','txz','zip'];
+EOF
+
+test_expect_success \
+ 'snapshots: all enabled in default, use default disabled value' \
+ 'gitweb_run "p=.git;a=snapshot;h=HEAD;sf=tgz" &&
+ grep "Status: 200 OK" gitweb.output &&
+ gitweb_run "p=.git;a=snapshot;h=HEAD;sf=tbz2" &&
+ grep "Status: 200 OK" gitweb.output &&
+ gitweb_run "p=.git;a=snapshot;h=HEAD;sf=txz" &&
+ grep "403 - Unsupported snapshot format" gitweb.output &&
+ gitweb_run "p=.git;a=snapshot;h=HEAD;sf=zip" &&
+ grep "Status: 200 OK" gitweb.output'
+test_debug 'cat gitweb.output'
+
+
+cat >>gitweb_config.perl <<EOF
+
+\$known_snapshot_formats{'zip'}{'disabled'} = 1;
+EOF
+
+test_expect_success \
+ 'snapshots: zip explicitly disabled' \
+ 'gitweb_run "p=.git;a=snapshot;h=HEAD;sf=zip" &&
+ grep "403 - Unsupported snapshot format" gitweb.output'
+test_debug 'cat gitweb.output'
+
+
+cat >>gitweb_config.perl <<EOF
+
+\$known_snapshot_formats{'tgz'}{'disabled'} = 0;
+EOF
+
+test_expect_success \
+ 'snapshots: tgz explicitly enabled' \
+ 'gitweb_run "p=.git;a=snapshot;h=HEAD;sf=tgz" &&
+ grep "Status: 200 OK" gitweb.output'
+test_debug 'cat gitweb.output'
+
+
test_done
--
1.6.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox