Re: in_merge_bases() is too expensive for recent pu update
Junio C Hamano gits...@pobox.com writes: Thomas Rast tr...@student.ethz.ch writes: diff --git i/commit.c w/commit.c index 65a8485..70427ab 100644 --- i/commit.c +++ w/commit.c @@ -837,10 +837,13 @@ int in_merge_bases(struct commit *commit, struct commit **reference, int num) struct commit_list *bases, *b; int ret = 0; -if (num == 1) -bases = get_merge_bases(commit, *reference, 1); -else +if (num != 1) die(not yet); + +bases = merge_bases_many(commit, 1, reference); +clear_commit_marks(commit, all_flags); +clear_commit_marks(*reference, all_flags); + for (b = bases; b; b = b-next) { if (!hashcmp(commit-object.sha1, b-item-object.sha1)) { ret = 1; This ended up being part of the series I sent earlier, and I want to assign authorship to you. As you did this as part of the discussion, naturally the patch came without a sign-off. Can we consider it signed off? Just saying ok is fine. Sure: ok ;-) I'm also mildly surprised that it ended up being correct, albeit with some extra work from you :-) -- Thomas Rast trast@{inf,student}.ethz.ch -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v7 00/16] GSOC remote-svn
Reroll includes fixups by Ramsey. Thanks! Diff: - Add missing dependency to rule in Makefile. - improve compatibility of integer types. - t9020-*.sh: remove excess slash in urls that makes python on windows interpret it as a network path. - t9020-*.sh: skip if python isn't available. - replace getline() in remote-testsvn.c. There are platforms that don't provide this function. [PATCH v7 01/16] Implement a remote helper for svn in C [PATCH v7 02/16] Add git-remote-testsvn to Makefile [PATCH v7 03/16] Add svndump_init_fd to allow reading dumps from [PATCH v7 04/16] Add argv_array_detach and argv_array_free_detached [PATCH v7 05/16] Connect fast-import to the remote-helper via pipe, [PATCH v7 06/16] Add documentation for the 'bidi-import' capability [PATCH v7 07/16] When debug==1, start fast-import with --stats [PATCH v7 08/16] remote-svn, vcs-svn: Enable fetching to private [PATCH v7 09/16] Allow reading svn dumps from files via file:// urls [PATCH v7 10/16] vcs-svn: add fast_export_note to create notes [PATCH v7 11/16] Create a note for every imported commit containing [PATCH v7 12/16] remote-svn: Activate import/export-marks for [PATCH v7 13/16] remote-svn: add incremental import [PATCH v7 14/16] Add a svnrdump-simulator replaying a dump file for [PATCH v7 15/16] remote-svn: add marks-file regeneration [PATCH v7 16/16] Add a test script for remote-svn -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v7 01/16] Implement a remote helper for svn in C
Enable basic fetching from subversion repositories. When processing remote URLs starting with testsvn::, git invokes this remote-helper. It starts svnrdump to extract revisions from the subversion repository in the 'dump file format', and converts them to a git-fast-import stream using the functions of vcs-svn/. Imported refs are created in a private namespace at refs/svn/remote-name/master. The revision history is imported linearly (no branch detection) and completely, i.e. from revision 0 to HEAD. The 'bidi-import' capability is used. The remote-helper expects data from fast-import on its stdin. It buffers a batch of 'import' command lines in a string_list before starting to process them. Signed-off-by: Florian Achleitner florian.achleitner.2.6...@gmail.com Signed-off-by: Junio C Hamano gits...@pobox.com --- remote-testsvn.c | 174 ++ 1 file changed, 174 insertions(+) create mode 100644 remote-testsvn.c diff --git a/remote-testsvn.c b/remote-testsvn.c new file mode 100644 index 000..ebe803b --- /dev/null +++ b/remote-testsvn.c @@ -0,0 +1,174 @@ +#include cache.h +#include remote.h +#include strbuf.h +#include url.h +#include exec_cmd.h +#include run-command.h +#include vcs-svn/svndump.h +#include notes.h +#include argv-array.h + +static const char *url; +static const char *private_ref; +static const char *remote_ref = refs/heads/master; + +static int cmd_capabilities(const char *line); +static int cmd_import(const char *line); +static int cmd_list(const char *line); + +typedef int (*input_command_handler)(const char *); +struct input_command_entry { + const char *name; + input_command_handler fn; + unsigned char batchable;/* whether the command starts or is part of a batch */ +}; + +static const struct input_command_entry input_command_list[] = { + { capabilities, cmd_capabilities, 0 }, + { import, cmd_import, 1 }, + { list, cmd_list, 0 }, + { NULL, NULL } +}; + +static int cmd_capabilities(const char *line) { + printf(import\n); + printf(bidi-import\n); + printf(refspec %s:%s\n\n, remote_ref, private_ref); + fflush(stdout); + return 0; +} + +static void terminate_batch(void) +{ + /* terminate a current batch's fast-import stream */ + printf(done\n); + fflush(stdout); +} + +static int cmd_import(const char *line) +{ + int code; + int dumpin_fd; + unsigned int startrev = 0; + struct argv_array svndump_argv = ARGV_ARRAY_INIT; + struct child_process svndump_proc; + + memset(svndump_proc, 0, sizeof(struct child_process)); + svndump_proc.out = -1; + argv_array_push(svndump_argv, svnrdump); + argv_array_push(svndump_argv, dump); + argv_array_push(svndump_argv, url); + argv_array_pushf(svndump_argv, -r%u:HEAD, startrev); + svndump_proc.argv = svndump_argv.argv; + + code = start_command(svndump_proc); + if (code) + die(Unable to start %s, code %d, svndump_proc.argv[0], code); + dumpin_fd = svndump_proc.out; + + svndump_init_fd(dumpin_fd, STDIN_FILENO); + svndump_read(url, private_ref); + svndump_deinit(); + svndump_reset(); + + close(dumpin_fd); + code = finish_command(svndump_proc); + if (code) + warning(%s, returned %d, svndump_proc.argv[0], code); + argv_array_clear(svndump_argv); + + return 0; +} + +static int cmd_list(const char *line) +{ + printf(? %s\n\n, remote_ref); + fflush(stdout); + return 0; +} + +static int do_command(struct strbuf *line) +{ + const struct input_command_entry *p = input_command_list; + static struct string_list batchlines = STRING_LIST_INIT_DUP; + static const struct input_command_entry *batch_cmd; + /* +* commands can be grouped together in a batch. +* Batches are ended by \n. If no batch is active the program ends. +* During a batch all lines are buffered and passed to the handler function +* when the batch is terminated. +*/ + if (line-len == 0) { + if (batch_cmd) { + struct string_list_item *item; + for_each_string_list_item(item, batchlines) + batch_cmd-fn(item-string); + terminate_batch(); + batch_cmd = NULL; + string_list_clear(batchlines, 0); + return 0; /* end of the batch, continue reading other commands. */ + } + return 1; /* end of command stream, quit */ + } + if (batch_cmd) { + if (prefixcmp(batch_cmd-name, line-buf)) + die(Active %s batch interrupted by %s, batch_cmd-name, line-buf); + /* buffer batch lines */ + string_list_append(batchlines, line-buf); +
[PATCH v7 06/16] Add documentation for the 'bidi-import' capability of remote-helpers
Signed-off-by: Florian Achleitner florian.achleitner.2.6...@gmail.com Signed-off-by: Junio C Hamano gits...@pobox.com --- Documentation/git-remote-helpers.txt | 21 - 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/Documentation/git-remote-helpers.txt b/Documentation/git-remote-helpers.txt index f5836e4..5ce4cda 100644 --- a/Documentation/git-remote-helpers.txt +++ b/Documentation/git-remote-helpers.txt @@ -98,6 +98,20 @@ advertised with this capability must cover all refs reported by the list command. If no 'refspec' capability is advertised, there is an implied `refspec *:*`. +'bidi-import':: + The fast-import commands 'cat-blob' and 'ls' can be used by remote-helpers + to retrieve information about blobs and trees that already exist in + fast-import's memory. This requires a channel from fast-import to the + remote-helper. + If it is advertised in addition to import, git establishes a pipe from + fast-import to the remote-helper's stdin. + It follows that git and fast-import are both connected to the + remote-helper's stdin. Because git can send multiple commands to + the remote-helper it is required that helpers that use 'bidi-import' + buffer all 'import' commands of a batch before sending data to fast-import. + This is to prevent mixing commands and fast-import responses on the + helper's stdin. + Capabilities for Pushing 'connect':: @@ -286,7 +300,12 @@ terminated with a blank line. For each batch of 'import', the remote helper should produce a fast-import stream terminated by a 'done' command. + -Supported if the helper has the import capability. +Note that if the 'bidi-import' capability is used the complete batch +sequence has to be buffered before starting to send data to fast-import +to prevent mixing of commands and fast-import responses on the helper's +stdin. ++ +Supported if the helper has the 'import' capability. 'connect' service:: Connects to given service. Standard input and standard output -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v7 09/16] Allow reading svn dumps from files via file:// urls
For testing as well as for importing large, already available dumps, it's useful to bypass svnrdump and replay the svndump from a file directly. Add support for file:// urls in the remote url, e.g. svn::file:///path/to/dump When the remote helper finds an url starting with file:// it tries to open that file instead of invoking svnrdump. Signed-off-by: Florian Achleitner florian.achleitner.2.6...@gmail.com Signed-off-by: Junio C Hamano gits...@pobox.com --- remote-testsvn.c | 55 +++--- 1 file changed, 36 insertions(+), 19 deletions(-) diff --git a/remote-testsvn.c b/remote-testsvn.c index ebe803b..2b9d151 100644 --- a/remote-testsvn.c +++ b/remote-testsvn.c @@ -9,6 +9,7 @@ #include argv-array.h static const char *url; +static int dump_from_file; static const char *private_ref; static const char *remote_ref = refs/heads/master; @@ -53,29 +54,38 @@ static int cmd_import(const char *line) struct argv_array svndump_argv = ARGV_ARRAY_INIT; struct child_process svndump_proc; - memset(svndump_proc, 0, sizeof(struct child_process)); - svndump_proc.out = -1; - argv_array_push(svndump_argv, svnrdump); - argv_array_push(svndump_argv, dump); - argv_array_push(svndump_argv, url); - argv_array_pushf(svndump_argv, -r%u:HEAD, startrev); - svndump_proc.argv = svndump_argv.argv; - - code = start_command(svndump_proc); - if (code) - die(Unable to start %s, code %d, svndump_proc.argv[0], code); - dumpin_fd = svndump_proc.out; - + if (dump_from_file) { + dumpin_fd = open(url, O_RDONLY); + if(dumpin_fd 0) { + die_errno(Couldn't open svn dump file %s., url); + } + } + else { + memset(svndump_proc, 0, sizeof(struct child_process)); + svndump_proc.out = -1; + argv_array_push(svndump_argv, svnrdump); + argv_array_push(svndump_argv, dump); + argv_array_push(svndump_argv, url); + argv_array_pushf(svndump_argv, -r%u:HEAD, startrev); + svndump_proc.argv = svndump_argv.argv; + + code = start_command(svndump_proc); + if (code) + die(Unable to start %s, code %d, svndump_proc.argv[0], code); + dumpin_fd = svndump_proc.out; + } svndump_init_fd(dumpin_fd, STDIN_FILENO); svndump_read(url, private_ref); svndump_deinit(); svndump_reset(); close(dumpin_fd); - code = finish_command(svndump_proc); - if (code) - warning(%s, returned %d, svndump_proc.argv[0], code); - argv_array_clear(svndump_argv); + if(!dump_from_file) { + code = finish_command(svndump_proc); + if (code) + warning(%s, returned %d, svndump_proc.argv[0], code); + argv_array_clear(svndump_argv); + } return 0; } @@ -149,8 +159,15 @@ int main(int argc, const char **argv) remote = remote_get(argv[1]); url_in = (argc == 3) ? argv[2] : remote-url[0]; - end_url_with_slash(buf, url_in); - url = strbuf_detach(buf, NULL); + if (!prefixcmp(url_in, file://)) { + dump_from_file = 1; + url = url_decode(url_in + sizeof(file://)-1); + } + else { + dump_from_file = 0; + end_url_with_slash(buf, url_in); + url = strbuf_detach(buf, NULL); + } strbuf_addf(buf, refs/svn/%s/master, remote-name); private_ref = strbuf_detach(buf, NULL); -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v7 08/16] remote-svn, vcs-svn: Enable fetching to private refs
The reference to update by the fast-import stream is hard-coded. When fetching from a remote the remote-helper shall update refs in a private namespace, i.e. a private subdir of refs/. This namespace is defined by the 'refspec' capability, that the remote-helper advertises as a reply to the 'capabilities' command. Extend svndump and fast-export to allow passing the target ref. Update svn-fe to be compatible. Signed-off-by: Florian Achleitner florian.achleitner.2.6...@gmail.com Signed-off-by: Junio C Hamano gits...@pobox.com --- contrib/svn-fe/svn-fe.c |2 +- test-svn-fe.c |2 +- vcs-svn/fast_export.c |4 ++-- vcs-svn/fast_export.h |2 +- vcs-svn/svndump.c | 14 +++--- vcs-svn/svndump.h |2 +- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/contrib/svn-fe/svn-fe.c b/contrib/svn-fe/svn-fe.c index 35db24f..c796cc0 100644 --- a/contrib/svn-fe/svn-fe.c +++ b/contrib/svn-fe/svn-fe.c @@ -10,7 +10,7 @@ int main(int argc, char **argv) { if (svndump_init(NULL)) return 1; - svndump_read((argc 1) ? argv[1] : NULL); + svndump_read((argc 1) ? argv[1] : NULL, refs/heads/master); svndump_deinit(); svndump_reset(); return 0; diff --git a/test-svn-fe.c b/test-svn-fe.c index 83633a2..cb0d80f 100644 --- a/test-svn-fe.c +++ b/test-svn-fe.c @@ -40,7 +40,7 @@ int main(int argc, char *argv[]) if (argc == 2) { if (svndump_init(argv[1])) return 1; - svndump_read(NULL); + svndump_read(NULL, refs/heads/master); svndump_deinit(); svndump_reset(); return 0; diff --git a/vcs-svn/fast_export.c b/vcs-svn/fast_export.c index 1f04697..11f8f94 100644 --- a/vcs-svn/fast_export.c +++ b/vcs-svn/fast_export.c @@ -72,7 +72,7 @@ static char gitsvnline[MAX_GITSVN_LINE_LEN]; void fast_export_begin_commit(uint32_t revision, const char *author, const struct strbuf *log, const char *uuid, const char *url, - unsigned long timestamp) + unsigned long timestamp, const char *local_ref) { static const struct strbuf empty = STRBUF_INIT; if (!log) @@ -84,7 +84,7 @@ void fast_export_begin_commit(uint32_t revision, const char *author, } else { *gitsvnline = '\0'; } - printf(commit refs/heads/master\n); + printf(commit %s\n, local_ref); printf(mark :%PRIu32\n, revision); printf(committer %s %s@%s %ld +\n, *author ? author : nobody, diff --git a/vcs-svn/fast_export.h b/vcs-svn/fast_export.h index 8823aca..17eb13b 100644 --- a/vcs-svn/fast_export.h +++ b/vcs-svn/fast_export.h @@ -11,7 +11,7 @@ void fast_export_delete(const char *path); void fast_export_modify(const char *path, uint32_t mode, const char *dataref); void fast_export_begin_commit(uint32_t revision, const char *author, const struct strbuf *log, const char *uuid, - const char *url, unsigned long timestamp); + const char *url, unsigned long timestamp, const char *local_ref); void fast_export_end_commit(uint32_t revision); void fast_export_data(uint32_t mode, off_t len, struct line_buffer *input); void fast_export_blob_delta(uint32_t mode, diff --git a/vcs-svn/svndump.c b/vcs-svn/svndump.c index d81a078..288bb42 100644 --- a/vcs-svn/svndump.c +++ b/vcs-svn/svndump.c @@ -299,22 +299,22 @@ static void handle_node(void) node_ctx.text_length, input); } -static void begin_revision(void) +static void begin_revision(const char *remote_ref) { if (!rev_ctx.revision) /* revision 0 gets no git commit. */ return; fast_export_begin_commit(rev_ctx.revision, rev_ctx.author.buf, rev_ctx.log, dump_ctx.uuid.buf, dump_ctx.url.buf, - rev_ctx.timestamp); + rev_ctx.timestamp, remote_ref); } -static void end_revision(void) +static void end_revision() { if (rev_ctx.revision) fast_export_end_commit(rev_ctx.revision); } -void svndump_read(const char *url) +void svndump_read(const char *url, const char *local_ref) { char *val; char *t; @@ -353,7 +353,7 @@ void svndump_read(const char *url) if (active_ctx == NODE_CTX) handle_node(); if (active_ctx == REV_CTX) - begin_revision(); + begin_revision(local_ref); if (active_ctx != DUMP_CTX) end_revision(); active_ctx = REV_CTX; @@ -366,7 +366,7 @@ void svndump_read(const char *url) if (active_ctx == NODE_CTX)
Re: [PATCH v7 00/16] GSOC remote-svn
On Tuesday 28 August 2012 10:49:34 Florian Achleitner wrote: Reroll includes fixups by Ramsey. Thanks! Diff: [..] - improve compatibility of integer types. [..] This line is wrong in this series. Just delete it. Sorry. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC v2 3/4] vcs-svn/svndump: rewrite handle_node(), begin|end_revision()
Split the decision of what to do and actually doing it in handle_node() to allow for detection of branches from svn nodes. Split it into handle_node() and apply_node(). svn dumps are structured in revisions, which contain multiple nodes. Nodes represent operations on data. Currently the function handle_node() strongly mixes the interpretation of the node data with the output of processed data to fast-import. In a fast-import stream a commit object requires a branch name to which the new commit is added at its beginning. We want to detect branches in svn. This can only be done by analyzing node operations, like copyfrom. This conflicts with the current implementation, where at the beginning of each new revision in the svn dump, a new commit on a hard-coded git branch is created, before even reading the first node. To allow analyzing the nodes before deciding on which branch the commit will be placed, store the node metadata of one complete revision, and create a commit from it, when it ends. Each node can have file data appended. It's desirable to not store the actual file data, as it is unbounded. fast-import has a 'blob' command that allows writing blobs, independent of commits. Use this feature instead of sending data inline and send the actual file data immediately when it is read in. Use marks to reference a blob later. fast-import's marks are currently used for marking commits, where the mark number corresponds to exactly one svn revision. Store the marks for blobs in the upper half of the marks number space where the MSB is 1. Change handle_node() to interpret the node data, store it in a node_ctx, send blobs to fast-import, and append the new node_ctx to the list of node_ctx. Do this until the end of a revision. Just clear the list of note_ctx in begin_revision(). At end_revision() all node metadata is available in the node_ctx list. Future's branch detectors can decide what branches are to be changed. Then, call apply_node() for each of them to actually create a commit and change/add/delete files according to the node_ctx using the already added blobs. This can also be used to create commits if the node metadata does not come from a svndump, but is stored in e.g. notes, for later branch detection. Signed-off-by: Florian Achleitner florian.achleitner.2.6...@gmail.com Signed-off-by: Junio C Hamano gits...@pobox.com --- vcs-svn/svndump.c | 167 ++--- 1 file changed, 109 insertions(+), 58 deletions(-) diff --git a/vcs-svn/svndump.c b/vcs-svn/svndump.c index 385523a..eb97e8e 100644 --- a/vcs-svn/svndump.c +++ b/vcs-svn/svndump.c @@ -48,7 +48,6 @@ static struct node_ctx_t *node_list, *node_list_tail; static struct node_ctx_t *new_node_ctx(char *fname) { struct node_ctx_t *node = xmalloc(sizeof(struct node_ctx_t)); - trace_printf(new_node_ctx %p\n, node); node-type = 0; node-action = NODEACT_UNKNOWN; node-prop_length = -1; @@ -67,7 +66,6 @@ static struct node_ctx_t *new_node_ctx(char *fname) static void free_node_ctx(struct node_ctx_t *node) { - trace_printf(free_node_ctx %p\n, node); strbuf_release(node-src); strbuf_release(node-dst); free((char*)node-dataref); @@ -77,7 +75,6 @@ static void free_node_ctx(struct node_ctx_t *node) static void free_node_list(void) { struct node_ctx_t *p = node_list, *n; - trace_printf(free_node_list head %p tail %p\n, node_list, node_list_tail); while (p) { n = p-next; free_node_ctx(p); @@ -88,7 +85,6 @@ static void free_node_list(void) static void append_node_list(struct node_ctx_t *n) { - trace_printf(append_node_list %p head %p tail %p\n, n, node_list, node_list_tail); if (!node_list) node_list = node_list_tail = n; else { @@ -246,23 +242,10 @@ static void handle_node(struct node_ctx_t *node) static const char *const empty_blob = ::empty::; const char *old_data = NULL; uint32_t old_mode = REPO_MODE_BLB; + struct strbuf sb = STRBUF_INIT; + static uintmax_t blobmark = (uintmax_t) 1UL (bitsizeof(uintmax_t) - 1); + - if (node-action == NODEACT_DELETE) { - if (have_text || have_props || node-srcRev) - die(invalid dump: deletion node has - copyfrom info, text, or properties); - repo_delete(node-dst.buf); - return; - } - if (node-action == NODEACT_REPLACE) { - repo_delete(node-dst.buf); - node-action = NODEACT_ADD; - } - if (node-srcRev) { - repo_copy(node-srcRev, node-src.buf, node-dst.buf); - if (node-action == NODEACT_ADD) - node-action = NODEACT_CHANGE; - } if (have_text type == REPO_MODE_DIR) die(invalid dump: directories cannot have text attached); @@ -270,28 +253,61
[PATCH 0/3] Refactor checkout option handling
On Tue, Aug 28, 2012 at 10:55 AM, Junio C Hamano gits...@pobox.com wrote: The surrounding code is somewhat tricky and the code structure is brittle; there are places that update the opts.new_branch so the new location of this check has to be after them, and there is one codepath that having a bad value in it does not matter. I had to check the code outside the context of this patch a few times to convince myself that this patch does not break them. I'll queue the patch as-is for now, but we probably would want to see how we can structure it to be less brittle. I'll give it a shot. On top of master, not the checkout -b -t patch. The test suite passes, but we'll need more eyeballs for code moves like this. Nguyễn Thái Ngọc Duy (3): checkout: pass struct checkout_opts * as const pointer checkout: reorder option handling checkout: move branch guessing code out as a separate function builtin/checkout.c | 290 ++--- 1 file changed, 164 insertions(+), 126 deletions(-) -- 1.7.12.rc2.18.g61b472e -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] checkout: pass struct checkout_opts * as const pointer
This struct contains various switches to change checkout behavior and it feels somewhat safer to have the compiler reassure us that nowhere else changes it. One field that is changed, writeout_error, is split out and passed as another argument. Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com --- builtin/checkout.c | 37 + 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/builtin/checkout.c b/builtin/checkout.c index 7d922c6..3e3f086 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -33,7 +33,6 @@ struct checkout_opts { int force; int force_detach; int writeout_stage; - int writeout_error; int overwrite_ignore; /* not set by parse_options */ @@ -216,7 +215,7 @@ static int checkout_merged(int pos, struct checkout *state) } static int checkout_paths(struct tree *source_tree, const char **pathspec, - const char *prefix, struct checkout_opts *opts) + const char *prefix, const struct checkout_opts *opts) { int pos; struct checkout state; @@ -309,7 +308,8 @@ static int checkout_paths(struct tree *source_tree, const char **pathspec, return errs; } -static void show_local_changes(struct object *head, struct diff_options *opts) +static void show_local_changes(struct object *head, + const struct diff_options *opts) { struct rev_info rev; /* I think we want full paths, even if we're in a subdirectory. */ @@ -331,7 +331,8 @@ static void describe_detached_head(const char *msg, struct commit *commit) strbuf_release(sb); } -static int reset_tree(struct tree *tree, struct checkout_opts *o, int worktree) +static int reset_tree(struct tree *tree, const struct checkout_opts *o, + int worktree, int *writeout_error) { struct unpack_trees_options opts; struct tree_desc tree_desc; @@ -350,7 +351,7 @@ static int reset_tree(struct tree *tree, struct checkout_opts *o, int worktree) init_tree_desc(tree_desc, tree-buffer, tree-size); switch (unpack_trees(1, tree_desc, opts)) { case -2: - o-writeout_error = 1; + *writeout_error = 1; /* * We return 0 nevertheless, as the index is all right * and more importantly we have made best efforts to @@ -381,8 +382,10 @@ static void setup_branch_path(struct branch_info *branch) branch-path = strbuf_detach(buf, NULL); } -static int merge_working_tree(struct checkout_opts *opts, - struct branch_info *old, struct branch_info *new) +static int merge_working_tree(const struct checkout_opts *opts, + struct branch_info *old, + struct branch_info *new, + int *writeout_error) { int ret; struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file)); @@ -393,7 +396,7 @@ static int merge_working_tree(struct checkout_opts *opts, resolve_undo_clear(); if (opts-force) { - ret = reset_tree(new-commit-tree, opts, 1); + ret = reset_tree(new-commit-tree, opts, 1, writeout_error); if (ret) return ret; } else { @@ -479,7 +482,8 @@ static int merge_working_tree(struct checkout_opts *opts, o.verbosity = 0; work = write_tree_from_memory(o); - ret = reset_tree(new-commit-tree, opts, 1); + ret = reset_tree(new-commit-tree, opts, 1, +writeout_error); if (ret) return ret; o.ancestor = old-name; @@ -487,7 +491,8 @@ static int merge_working_tree(struct checkout_opts *opts, o.branch2 = local; merge_trees(o, new-commit-tree, work, old-commit-tree, result); - ret = reset_tree(new-commit-tree, opts, 0); + ret = reset_tree(new-commit-tree, opts, 0, +writeout_error); if (ret) return ret; } @@ -514,7 +519,7 @@ static void report_tracking(struct branch_info *new) strbuf_release(sb); } -static void update_refs_for_switch(struct checkout_opts *opts, +static void update_refs_for_switch(const struct checkout_opts *opts, struct branch_info *old, struct branch_info *new) { @@ -701,13 +706,13 @@ static void orphaned_commit_warning(struct commit *old, struct commit *new) free(refs.objects); } -static int switch_branches(struct checkout_opts *opts, struct branch_info *new) +static int
[PATCH 2/3] checkout: reorder option handling
checkout operates in three different modes. On top of that it tries to be smart by guessing the branch name for switching. This results in messy option handling code. This patch reorders it so: - easy option handling comes first - the big chunk of branch name guessing comes next - mode detection comes last. Once the mode is known, check again to see if users specify any incompatible options - the actual action is done Another slight improvement is always print branch name (or commit name) when printing errors related ot them. This helps catch the case where an option is mistaken as branch/commit. Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com --- builtin/checkout.c | 153 +++-- 1 file changed, 89 insertions(+), 64 deletions(-) diff --git a/builtin/checkout.c b/builtin/checkout.c index 3e3f086..3f1a436 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -760,8 +760,7 @@ static int git_checkout_config(const char *var, const char *value, void *cb) return git_xmerge_config(var, value, NULL); } -static int interactive_checkout(const char *revision, const char **pathspec, - struct checkout_opts *opts) +static int interactive_checkout(const char *revision, const char **pathspec) { return run_add_interactive(revision, --patch=checkout, pathspec); } @@ -937,6 +936,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) char *conflict_style = NULL; int patch_mode = 0; int dwim_new_local_branch = 1; + const char **pathspec = NULL; struct option options[] = { OPT__QUIET(opts.quiet, suppress progress reporting), OPT_STRING('b', NULL, opts.new_branch, branch, @@ -976,23 +976,45 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, options, checkout_usage, PARSE_OPT_KEEP_DASHDASH); - /* we can assume from now on new_branch = !new_branch_force */ - if (opts.new_branch opts.new_branch_force) - die(_(-B cannot be used with -b)); - - /* copy -B over to -b, so that we can just check the latter */ - if (opts.new_branch_force) - opts.new_branch = opts.new_branch_force; - - if (patch_mode (opts.track 0 || opts.new_branch - || opts.new_branch_log || opts.merge || opts.force - || opts.force_detach)) - die (_(--patch is incompatible with all other options)); - + /* Easy mode-independent incompatible checks */ if (opts.force_detach (opts.new_branch || opts.new_orphan_branch)) die(_(--detach cannot be used with -b/-B/--orphan)); if (opts.force_detach 0 opts.track) die(_(--detach cannot be used with -t)); + if (opts.force opts.merge) + die(_(git checkout: -f and -m are incompatible)); + + if (conflict_style) { + opts.merge = 1; /* implied */ + git_xmerge_config(merge.conflictstyle, conflict_style, NULL); + } + + /* +* opts.new_branch calculation, it could be from -b or -B or +* --track or --orphan or other command line arguments. +* +* The following code until new branch validation should not +* update any fields in opts but opts.new_branch. +*/ + if (opts.new_branch_force) { + /* we can assume from now on new_branch = !new_branch_force */ + if (opts.new_branch) + die(_(New branch '%s' is already specified by other options), + opts.new_branch); + + /* copy -B over to -b, so that we can just check the latter */ + if (opts.new_branch_force) + opts.new_branch = opts.new_branch_force; + } + + if (opts.new_orphan_branch) { + if (opts.track 0) + die(_(--orphan cannot be used with -t)); + if (opts.new_branch) + die(_(New branch '%s' is already specified by other options), + opts.new_branch); + opts.new_branch = opts.new_orphan_branch; + } /* --track without -b should DWIM */ if (0 opts.track !opts.new_branch) { @@ -1009,22 +1031,6 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) opts.new_branch = argv0 + 1; } - if (opts.new_orphan_branch) { - if (opts.new_branch) - die(_(--orphan and -b|-B are mutually exclusive)); - if (opts.track 0) - die(_(--orphan cannot be used with -t)); - opts.new_branch = opts.new_orphan_branch; - } - - if (conflict_style) { - opts.merge = 1; /* implied */ -
[PATCH 3/3] checkout: move branch guessing code out as a separate function
This makes cmd_checkout() shorter, therefore easier to get the big picture. Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com --- In general I like it, except that parse_branchname_arg() pulls so many options from cmd_checkout(). I would rather have update_new_branch() that only takes struct checkout_opts * and returns a new branch. So I'm not sure if we should do this. If we do, perhaps we can merge it into the previous patch. builtin/checkout.c | 184 - 1 file changed, 96 insertions(+), 88 deletions(-) diff --git a/builtin/checkout.c b/builtin/checkout.c index 3f1a436..e9d503d 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -914,6 +914,99 @@ static int parse_branchname_arg(int argc, const char **argv, return argcount; } +static const char *update_new_branch(const struct checkout_opts *opts, +int argc, const char **argv, +const char *prefix, const char ***pathspec, +int dwim_ok, +struct branch_info *new, +struct tree **source_tree, +unsigned char *rev) +{ + const char *branch = opts-new_branch; + + if (opts-new_branch_force) { + /* we can assume from now on new_branch = !new_branch_force */ + if (branch) + die(_(New branch '%s' is already specified by other options), + branch); + + /* copy -B over to -b, so that we can just check the latter */ + if (opts-new_branch_force) + branch = opts-new_branch_force; + } + + if (opts-new_orphan_branch) { + if (opts-track 0) + die(_(--orphan cannot be used with -t)); + if (branch) + die(_(New branch '%s' is already specified by other options), + branch); + branch = opts-new_orphan_branch; + } + + /* --track without -b should DWIM */ + if (0 opts-track !branch) { + const char *argv0 = argv[0]; + if (!argc || !strcmp(argv0, --)) + die (_(--track needs a branch name)); + if (!prefixcmp(argv0, refs/)) + argv0 += 5; + if (!prefixcmp(argv0, remotes/)) + argv0 += 8; + argv0 = strchr(argv0, '/'); + if (!argv0 || !argv0[1]) + die (_(Missing branch name; try -b)); + branch = argv0 + 1; + } + + /* +* Extract branch name from command line arguments, so +* all that is left is pathspecs. +* +* Handle +* +* 1) git checkout tree -- [paths] +* 2) git checkout -- [paths] +* 3) git checkout something [paths] +* +* including last branch syntax and DWIM-ery for names of +* remote branches, erroring out for invalid or ambiguous cases. +*/ + if (argc) { + dwim_ok = dwim_ok + opts-track == BRANCH_TRACK_UNSPECIFIED + !branch; + int n = parse_branchname_arg(argc, argv, dwim_ok, +new, source_tree, rev, branch); + argv += n; + argc -= n; + } + + /* After DWIM, these must be pathspec */ + if (argc) { + *pathspec = get_pathspec(prefix, argv); + + if (!*pathspec) + die(_(invalid path specification)); + + /* Try to give more helpful suggestion, new_branch + argc 1 will be caught later */ + if (branch argc == 1) + die(_(Cannot update paths and switch to branch '%s' at the same time.\n + Did you intend to checkout '%s' which can not be resolved as commit?), + branch, argv[0]); + + if (opts-force_detach) + die(_(git checkout: --detach does not take a path argument)); + + if (1 !!opts-writeout_stage + !!opts-force + !!opts-merge) + die(_(git checkout: --ours/--theirs, --force and --merge are incompatible when\n + checking out of the index.)); + } + + return branch; +} + static int switch_unborn_to_new_branch(const struct checkout_opts *opts) { int status; @@ -989,94 +1082,9 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) git_xmerge_config(merge.conflictstyle, conflict_style, NULL); } - /* -* opts.new_branch calculation, it could be from -b or -B or -* --track or --orphan or other command line
Utilisateurs francophones de systèmes de gestion de code source
Hello, I was looking for a french speaking place to discuss about Git, Hg, SVN and all other SCM in use and did not find. This is then an attempt to create one. I created a Google group: https://groups.google.com/forum/?fromgroups#!forum/sgcs-fr I invite french sepaking people to join. The group wouldn't be limited to one SCM but is global. The topic is the usage of all of them. Thank you. -- RMA. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: in_merge_bases() is too expensive for recent pu update
Thomas Rast tr...@inf.ethz.ch writes: I'm also mildly surprised that it ended up being correct, albeit with some extra work from you :-) I actually am not all that surprised. It just shows that the original code was layered in more or less the right way. At the the bottom layer we would want a way to paint graph down to common ancestors cheaply, and then on top we want to have a way to filter out the redundant ones. It is a different story that the implementation of individual layers may still have rooms for improvements (just like the last patch in my series showed for the upper layer where we used to do N * (N-1) when we only needed N). I have a suspicion that the merge_bases_many() at the bottom layer could be built on an even cheaper API. This caller you added does not need bases list returned; it only wants to see that ancestors of commit and reference down to their common ancestors are painted in two colors PARENT1 and PARENT2. Instead of iterating over the returned candidate list, we might be able to do common = PARENT1 | PARENT2; paint_ancestors(commit, 1, reference); commit_is_common = ((commit-object.flags common) == common); clear_commit_marks(commit, all_flags); clear_commit_marks(*reference, all_flags); where paint_ancestors() just paints but does not accumlate to return a commit_list. Note that paint_ancestors() need to always paint its arguments (merge_bases_many() has an early special case to return a list that only has commit when it appears in reference without painting anything, and the callers like get_merge_bases_many() know this to avoid calling clear_commit_marks()) if we are to go in this direction, so it is unclear if it will be overall gain. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff/merge tool that ignores whitespace changes
Hi folks, I'm looking for a diff / merge tool that treats lines with only whitespace changes (trailing or leading whitespaces, linefeeds, etc) as equal. The goal is to make reviews as well as merging or rebasing easier when things like indentions often change. Does anybody know an solution for that ? thx -- Mit freundlichen Grüßen / Kind regards Enrico Weigelt VNC - Virtual Network Consult GmbH Head Of Development Pariser Platz 4a, D-10117 Berlin Tel.: +49 (30) 3464615-20 Fax: +49 (30) 3464615-59 enrico.weig...@vnc.biz; www.vnc.de -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v7 02/16] Add git-remote-testsvn to Makefile
Florian Achleitner florian.achleitner.2.6...@gmail.com writes: The link-rule is a copy of the standard git$X rule but adds VCSSVN_LIB. Signed-off-by: Florian Achleitner florian.achleitner.2.6...@gmail.com Signed-off-by: Junio C Hamano gits...@pobox.com --- Makefile |5 + 1 file changed, 5 insertions(+) diff --git a/Makefile b/Makefile index 66e8216..1b09454 100644 --- a/Makefile +++ b/Makefile @@ -477,6 +477,7 @@ PROGRAM_OBJS += sh-i18n--envsubst.o PROGRAM_OBJS += shell.o PROGRAM_OBJS += show-index.o PROGRAM_OBJS += upload-pack.o +PROGRAM_OBJS += remote-testsvn.o # Binary suffix, set to .exe for Windows builds X = @@ -2352,6 +2353,10 @@ git-http-push$X: revision.o http.o http-push.o GIT-LDFLAGS $(GITLIBS) $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \ $(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT) +git-remote-testsvn$X: remote-testsvn.o GIT-LDFLAGS $(GITLIBS) $(VCSSVN_LIB) + $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS) \ + $(VCSSVN_LIB) + $(REMOTE_CURL_ALIASES): $(REMOTE_CURL_PRIMARY) $(QUIET_LNCP)$(RM) $@ \ ln $ $@ 2/dev/null || \ I'd squash in a change to add this executable to .gitignore (attached) to this patch. Unless you have objections to it, or suggestions to do it better, there is no need to resend. Thanks. .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git i/.gitignore w/.gitignore index bb5c91e..51294d6 100644 --- i/.gitignore +++ w/.gitignore @@ -125,6 +125,7 @@ /git-remote-fd /git-remote-ext /git-remote-testgit +/git-remote-testsvn /git-repack /git-replace /git-repo-config -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: diff/merge tool that ignores whitespace changes
- Original Message - From: Enrico Weigelt enrico.weig...@vnc.biz Sent: Tuesday, August 28, 2012 12:26:39 PM Subject: diff/merge tool that ignores whitespace changes I'm looking for a diff / merge tool that treats lines with only whitespace changes (trailing or leading whitespaces, linefeeds, etc) as equal. The goal is to make reviews as well as merging or rebasing easier when things like indentions often change. Does anybody know an solution for that ? I use kdiff3 which has the option to ignore whitespace changes (bonus: I can use it on all three major OSes as my work requires). It's GUI based, so that could be considered a downside to some. I usually use a combination of Git's built-in diff and kdiff to check my work. HTH, Stephen -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: diff/merge tool that ignores whitespace changes
On 08/28/2012 01:40 PM, Stephen Bash wrote: - Original Message - From: Enrico Weigelt enrico.weig...@vnc.biz Sent: Tuesday, August 28, 2012 12:26:39 PM Subject: diff/merge tool that ignores whitespace changes I'm looking for a diff / merge tool that treats lines with only whitespace changes (trailing or leading whitespaces, linefeeds, etc) as equal. The goal is to make reviews as well as merging or rebasing easier when things like indentions often change. Does anybody know an solution for that ? I'm fond of Meld. -- Matthew Caron, Software Build Engineer Sixnet, a Red Lion business | www.sixnet.com +1 (518) 877-5173 x138 office -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
I think git show is broken
(otherwise, there was a very strange change made to its functionality, which the documentation does not reflect) Old, working git: === $ git --version git version 1.7.0.4 $ git show --quiet --abbrev-commit --pretty=oneline 47a7aee54553fb718c376cfa9d7de4389a391e33 47a7aee Fix hyperlinks for dependent tickets (#7139, #4976). === New, broken git: === $ git --version git version 1.7.9.5 $ git show --quiet --abbrev-commit --pretty=oneline 47a7aee54553fb718c376cfa9d7de4389a391e33 47a7aee Fix hyperlinks for dependent tickets (#7139, #4976). diff --git a/mastertickets/web_ui.py b/mastertickets/web_ui.py index a91b862..698ed98 100644 --- a/mastertickets/web_ui.py +++ b/mastertickets/web_ui.py @@ -32,7 +32,7 @@ class MasterTicketsModule(Component): use_gs = BoolOption('mastertickets', 'use_gs', default=False, doc='If enabled, use ghostscript to produce nicer output.') -FIELD_XPATH = 'div[@id=ticket]/table[@class=properties]/td[@headers=h_%s]/text()' +FIELD_XPATH = './/div[@id=ticket]/table[@class=properties]//td[@headers=h_%s]/text()' fields = set(['blocking', 'blockedby']) # IRequestFilter methods === It appears as though the new functionality always puts out a medium verbosity diff. Though the manpage says that it honors pretty=oneline, it does not seem to. I searched around the message logs, etc. and would have expected this change to have thrown everyone else into as much upheaval as it has in my organization, and found nothing. Am I missing something? Thanks in advance. -- Matthew Caron, Software Build Engineer Sixnet, a Red Lion business | www.sixnet.com +1 (518) 877-5173 x138 office -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: I think git show is broken
On 08/28/2012 01:38 PM, Matthew Caron wrote: (otherwise, there was a very strange change made to its functionality, which the documentation does not reflect) Never mind. I was looking in the wrong spot. The issue is not with --pretty=oneline, it's with --quiet. In 1.7.0.4, --quiet worked like -s. It no longer does in 1.7.9.5. Switching to -s cures the problem. -- Matthew Caron, Software Build Engineer Sixnet, a Red Lion business | www.sixnet.com +1 (518) 877-5173 x138 office -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: libgit2 status
Nicolas Sebrecht nicolas.s@gmx.fr writes: Do you expect one big merge of a very stable libgit2 at some point? I don't think there's any need to merge libgit2 into the git project source. As a library, it should be perfectly usable as a project of its own, just like libcurl and libz. Otherwise, what about going with this optionnal LDFLAGS += -libgit2 ASAP with good disclaimer that it's only intended for development and testing purpose? Then, git-core could slowly rely on functions of libgit2, one after the other. This makes a lot of sense to me. -David -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v7 01/16] Implement a remote helper for svn in C
Florian Achleitner florian.achleitner.2.6...@gmail.com writes: Enable basic fetching from subversion repositories. When processing remote URLs starting with testsvn::, git invokes this remote-helper. It starts svnrdump to extract revisions from the subversion repository in the 'dump file format', and converts them to a git-fast-import stream using the functions of vcs-svn/. Imported refs are created in a private namespace at refs/svn/remote-name/master. The revision history is imported linearly (no branch detection) and completely, i.e. from revision 0 to HEAD. The 'bidi-import' capability is used. The remote-helper expects data from fast-import on its stdin. It buffers a batch of 'import' command lines in a string_list before starting to process them. Signed-off-by: Florian Achleitner florian.achleitner.2.6...@gmail.com Signed-off-by: Junio C Hamano gits...@pobox.com --- remote-testsvn.c | 174 ++ 1 file changed, 174 insertions(+) create mode 100644 remote-testsvn.c diff --git a/remote-testsvn.c b/remote-testsvn.c new file mode 100644 index 000..ebe803b --- /dev/null +++ b/remote-testsvn.c @@ -0,0 +1,174 @@ +#include cache.h +#include remote.h +#include strbuf.h +#include url.h +#include exec_cmd.h +#include run-command.h +#include vcs-svn/svndump.h +#include notes.h +#include argv-array.h + +static const char *url; +static const char *private_ref; +static const char *remote_ref = refs/heads/master; + +static int cmd_capabilities(const char *line); +static int cmd_import(const char *line); +static int cmd_list(const char *line); + +typedef int (*input_command_handler)(const char *); +struct input_command_entry { + const char *name; + input_command_handler fn; + unsigned char batchable;/* whether the command starts or is part of a batch */ +}; + +static const struct input_command_entry input_command_list[] = { + { capabilities, cmd_capabilities, 0 }, + { import, cmd_import, 1 }, + { list, cmd_list, 0 }, + { NULL, NULL } +}; + +static int cmd_capabilities(const char *line) { Style: static int cmd_capabilities(const char *line) { + printf(import\n); + printf(bidi-import\n); + printf(refspec %s:%s\n\n, remote_ref, private_ref); + fflush(stdout); + return 0; +} + +static void terminate_batch(void) +{ + /* terminate a current batch's fast-import stream */ + printf(done\n); + fflush(stdout); +} + +static int cmd_import(const char *line) +{ + int code; + int dumpin_fd; + unsigned int startrev = 0; + struct argv_array svndump_argv = ARGV_ARRAY_INIT; + struct child_process svndump_proc; + + memset(svndump_proc, 0, sizeof(struct child_process)); + svndump_proc.out = -1; + argv_array_push(svndump_argv, svnrdump); + argv_array_push(svndump_argv, dump); + argv_array_push(svndump_argv, url); + argv_array_pushf(svndump_argv, -r%u:HEAD, startrev); + svndump_proc.argv = svndump_argv.argv; + + code = start_command(svndump_proc); + if (code) + die(Unable to start %s, code %d, svndump_proc.argv[0], code); + dumpin_fd = svndump_proc.out; + + svndump_init_fd(dumpin_fd, STDIN_FILENO); + svndump_read(url, private_ref); + svndump_deinit(); + svndump_reset(); + + close(dumpin_fd); + code = finish_command(svndump_proc); + if (code) + warning(%s, returned %d, svndump_proc.argv[0], code); + argv_array_clear(svndump_argv); + + return 0; +} + +static int cmd_list(const char *line) +{ + printf(? %s\n\n, remote_ref); + fflush(stdout); + return 0; +} + +static int do_command(struct strbuf *line) +{ + const struct input_command_entry *p = input_command_list; + static struct string_list batchlines = STRING_LIST_INIT_DUP; + static const struct input_command_entry *batch_cmd; + /* + * commands can be grouped together in a batch. + * Batches are ended by \n. If no batch is active the program ends. + * During a batch all lines are buffered and passed to the handler function + * when the batch is terminated. + */ + if (line-len == 0) { + if (batch_cmd) { + struct string_list_item *item; + for_each_string_list_item(item, batchlines) + batch_cmd-fn(item-string); + terminate_batch(); + batch_cmd = NULL; + string_list_clear(batchlines, 0); + return 0; /* end of the batch, continue reading other commands. */ + } + return 1; /* end of command stream, quit */ + } + if (batch_cmd) { + if (prefixcmp(batch_cmd-name, line-buf)) + die(Active %s batch
Re: [PATCH v7 13/16] remote-svn: add incremental import
Florian Achleitner florian.achleitner.2.6...@gmail.com writes: Search for a note attached to the ref to update and read it's 'Revision-number:'-line. Start import from the next svn revision. If there is no next revision in the svn repo, svnrdump terminates with a message on stderr an non-zero return value. This looks a little weird, but there is no other way to know whether there is a new revision in the svn repo. On the start of an incremental import, the parent of the first commit in the fast-import stream is set to the branch name to update. All following commits specify their parent by a mark number. Previous mark files are currently not reused. Signed-off-by: Florian Achleitner florian.achleitner.2.6...@gmail.com Signed-off-by: Junio C Hamano gits...@pobox.com --- contrib/svn-fe/svn-fe.c |3 ++- remote-testsvn.c| 67 --- test-svn-fe.c |2 +- vcs-svn/fast_export.c | 10 +-- vcs-svn/fast_export.h |6 ++--- vcs-svn/svndump.c | 10 +++ vcs-svn/svndump.h |2 +- 7 files changed, 84 insertions(+), 16 deletions(-) diff --git a/contrib/svn-fe/svn-fe.c b/contrib/svn-fe/svn-fe.c index c796cc0..f363505 100644 --- a/contrib/svn-fe/svn-fe.c +++ b/contrib/svn-fe/svn-fe.c @@ -10,7 +10,8 @@ int main(int argc, char **argv) { if (svndump_init(NULL)) return 1; - svndump_read((argc 1) ? argv[1] : NULL, refs/heads/master); + svndump_read((argc 1) ? argv[1] : NULL, refs/heads/master, + refs/notes/svn/revs); svndump_deinit(); svndump_reset(); return 0; diff --git a/remote-testsvn.c b/remote-testsvn.c index b6e7968..e90d221 100644 --- a/remote-testsvn.c +++ b/remote-testsvn.c @@ -12,7 +12,8 @@ static const char *url; static int dump_from_file; static const char *private_ref; static const char *remote_ref = refs/heads/master; -static const char *marksfilename; +static const char *marksfilename, *notes_ref; +struct rev_note { unsigned int rev_nr; }; static int cmd_capabilities(const char *line); static int cmd_import(const char *line); @@ -47,14 +48,70 @@ static void terminate_batch(void) fflush(stdout); } +/* NOTE: 'ref' refers to a git reference, while 'rev' refers to a svn revision. */ +static char *read_ref_note(const unsigned char sha1[20]) { Style: static char *read_ref_note(const unsigned char sha1[20]) { + const unsigned char *note_sha1; + char *msg = NULL; + unsigned long msglen; + enum object_type type; + init_notes(NULL, notes_ref, NULL, 0); + if( (note_sha1 = get_note(NULL, sha1)) == NULL || + !(msg = read_sha1_file(note_sha1, type, msglen)) || + !msglen || type != OBJ_BLOB) { + free(msg); + return NULL; + } + free_notes(NULL); + return msg; +} Style: if (!(note_sha1 = get_note(NULL, sha1)) || !(msg = read_sha1_file(note_sha1, type, msglen)) || !msglen || type != OBJ_BLOB) { ... But a bigger question is if any of these cases is a non-error. It may be perfectly normal so get_note() that returns NULL may be a normal condition, but is it something you want to silently ignore if read_sha1_file() did not give you anything when called with a note_sha1 that ought to be valid? How about the case where you got msg but msglen is zero? Is it an error? Is it normal and the caller wants to see a note that happens to be an empty string? How about the case where the note returned was ot a blob? Is it something you want to silently ignore, or is it an error? Having multiple assingments inside a conditional, and chaining them together with ||, lets you code lazily, and the resulting code like the above _appear_ concise, but in order to prepare the code to answer these questions sensibly, it is often a good habit to avoid the appearance of conciseness that hides the lack of thought (e.g. the code is hiding the reason why it does not call free_notes() when you do have note_sah1 but found a note that is of undesired object type, and the reader cannot tell if it is done deliberately). It is far more preferrable to see this written like: if (!(note_sha1 = get_note(NULL, sha1))) return NULL; /* no notes - nothing to return */ msg = read_sha1_file(note_sha1, type, msglen); if (!msg) { error(cannot read notes for ...); } else if (type != OBJ_BLOB) { free(msg); /* something we cannot use */ msg = NULL; } ... you may have more else if clauses here ... free_notes(NULL); return msg; Also, I am not sure if you want to silently ignore OBJ_BLOB here. If I understand correctly, you are not reading from a random notes tree, but from a notes tree that was populated by an
Re: [PATCH v7 15/16] remote-svn: add marks-file regeneration
Florian Achleitner florian.achleitner.2.6...@gmail.com writes: fast-import mark files are stored outside the object database and are therefore not fetched and can be lost somehow else. marks provide a svn revision -- git sha1 mapping, while the notes that are attached to each commit when it is imported provide a git sha1 -- svn revision mapping. If the marks file is not available or not plausible, regenerate it by walking through the notes tree. , i.e. The plausibility check tests if the highest revision in the marks file matches the revision of the top ref. It doesn't ensure that the mark file is completely correct. This could only be done with an effort equal to unconditional regeneration. Signed-off-by: Florian Achleitner florian.achleitner.2.6...@gmail.com Signed-off-by: Junio C Hamano gits...@pobox.com --- remote-testsvn.c | 68 ++ 1 file changed, 68 insertions(+) diff --git a/remote-testsvn.c b/remote-testsvn.c index e90d221..d0b81d5 100644 --- a/remote-testsvn.c +++ b/remote-testsvn.c @@ -86,6 +86,73 @@ static int parse_rev_note(const char *msg, struct rev_note *res) { return 0; } +static int note2mark_cb(const unsigned char *object_sha1, + const unsigned char *note_sha1, char *note_path, + void *cb_data) { + FILE *file = (FILE *)cb_data; + char *msg; + unsigned long msglen; + enum object_type type; + struct rev_note note; + if (!(msg = read_sha1_file(note_sha1, type, msglen)) || + !msglen || type != OBJ_BLOB) { + free(msg); + return 1; + } The same comments as an earlier patch in the series applies here, regarding chained assignments in coditional, whether each case is an error that needs to be reported, and the sign of the error return value. + if (parse_rev_note(msg, note)) + return 2; + if (fprintf(file, :%d %s\n, note.rev_nr, sha1_to_hex(object_sha1)) 1) + return 3; + return 0; +} + +static void regenerate_marks(void) +{ + int ret; + FILE *marksfile; + marksfile = fopen(marksfilename, w+); + if (!marksfile) + die_errno(Couldn't create mark file %s., marksfilename); + ret = for_each_note(NULL, 0, note2mark_cb, marksfile); + if (ret) + die(Regeneration of marks failed, returned %d., ret); + fclose(marksfile); +} + +static void check_or_regenerate_marks(int latestrev) { Style. + FILE *marksfile; + struct strbuf sb = STRBUF_INIT; + struct strbuf line = STRBUF_INIT; + int found = 0; + + if (latestrev 1) + return; It's more pleasant to read to have a blank line between the end of decls and the first statement, like this function does. Please fix two functions that appear before this function in this file to match. + init_notes(NULL, notes_ref, NULL, 0); + marksfile = fopen(marksfilename, r); + if (!marksfile) { + regenerate_marks(); + marksfile = fopen(marksfilename, r); + if (!marksfile) + die_errno(cannot read marks file %s!, marksfilename); + fclose(marksfile); + } else { + strbuf_addf(sb, :%d , latestrev); + while (strbuf_getline(line, marksfile, '\n') != EOF) { + if (!prefixcmp(line.buf, sb.buf)) { + found++; + break; + } + } + fclose(marksfile); + if (!found) + regenerate_marks(); + } + free_notes(NULL); + strbuf_release(sb); + strbuf_release(line); +} + static int cmd_import(const char *line) { int code; @@ -111,6 +178,7 @@ static int cmd_import(const char *line) free(note_msg); } } + check_or_regenerate_marks(startrev - 1); if (dump_from_file) { dumpin_fd = open(url, O_RDONLY); -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v7 08/16] remote-svn, vcs-svn: Enable fetching to private refs
Florian Achleitner florian.achleitner.2.6...@gmail.com writes: The reference to update by the fast-import stream is hard-coded. When fetching from a remote the remote-helper shall update refs in a private namespace, i.e. a private subdir of refs/. This namespace is defined by the 'refspec' capability, that the remote-helper advertises as a reply to the 'capabilities' command. Extend svndump and fast-export to allow passing the target ref. Update svn-fe to be compatible. Signed-off-by: Florian Achleitner florian.achleitner.2.6...@gmail.com Signed-off-by: Junio C Hamano gits...@pobox.com --- ... diff --git a/vcs-svn/svndump.c b/vcs-svn/svndump.c index d81a078..288bb42 100644 --- a/vcs-svn/svndump.c +++ b/vcs-svn/svndump.c @@ -299,22 +299,22 @@ static void handle_node(void) node_ctx.text_length, input); } -static void begin_revision(void) +static void begin_revision(const char *remote_ref) { if (!rev_ctx.revision) /* revision 0 gets no git commit. */ return; fast_export_begin_commit(rev_ctx.revision, rev_ctx.author.buf, rev_ctx.log, dump_ctx.uuid.buf, dump_ctx.url.buf, - rev_ctx.timestamp); + rev_ctx.timestamp, remote_ref); } -static void end_revision(void) +static void end_revision() Don't. { if (rev_ctx.revision) fast_export_end_commit(rev_ctx.revision); } -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v7 16/16] Add a test script for remote-svn
Florian Achleitner florian.achleitner.2.6...@gmail.com writes: Use svnrdump_sim.py to emulate svnrdump without an svn server. Tests fetching, incremental fetching, fetching from file://, and the regeneration of fast-import's marks file. Signed-off-by: Florian Achleitner florian.achleitner.2.6...@gmail.com Signed-off-by: Junio C Hamano gits...@pobox.com --- t/t9020-remote-svn.sh | 82 + 1 file changed, 82 insertions(+) create mode 100755 t/t9020-remote-svn.sh diff --git a/t/t9020-remote-svn.sh b/t/t9020-remote-svn.sh new file mode 100755 index 000..e6ed4ca --- /dev/null +++ b/t/t9020-remote-svn.sh @@ -0,0 +1,82 @@ +#!/bin/sh + +test_description='tests remote-svn' + +. ./test-lib.sh + +if ! test_have_prereq PYTHON +then + skip_all='skipping remote-svn tests, python not available' + test_done +fi + +# We override svnrdump by placing a symlink to the svnrdump-emulator in . +export PATH=$HOME:$PATH +ln -sf $GIT_BUILD_DIR/contrib/svn-fe/svnrdump_sim.py $HOME/svnrdump + +init_git () { + rm -fr .git + git init + #git remote add svnsim testsvn::sim:///$TEST_DIRECTORY/t9020/example.svnrdump + # let's reuse an exisiting dump file!? + git remote add svnsim testsvn::sim://$TEST_DIRECTORY/t9154/svn.dump + git remote add svnfile testsvn::file://$TEST_DIRECTORY/t9154/svn.dump +} + +if test -e $GIT_BUILD_DIR/git-remote-testsvn +then + test_set_prereq REMOTE_SVN +fi + +test_debug ' + git --version + which git + which svnrdump +' + +test_expect_success REMOTE_SVN 'simple fetch' ' + init_git + git fetch svnsim + test_cmp .git/refs/svn/svnsim/master .git/refs/remotes/svnsim/master + cp .git/refs/remotes/svnsim/master master.good +' + +test_debug ' + cat .git/refs/svn/svnsim/master + cat .git/refs/remotes/svnsim/master +' + +test_expect_success REMOTE_SVN 'repeated fetch, nothing shall change' ' + git fetch svnsim + test_cmp master.good .git/refs/remotes/svnsim/master +' + +test_expect_success REMOTE_SVN 'fetch from a file:// url gives the same result' ' + git fetch svnfile +' + +test_expect_failure REMOTE_SVN 'the sha1 differ because the git-svn-id line in the commit msg contains the url' ' + test_cmp .git/refs/remotes/svnfile/master .git/refs/remotes/svnsim/master +' + +test_expect_success REMOTE_SVN 'mark-file regeneration' ' + # filter out any other marks, that can not be regenerated. Only up to 3 digit revisions are allowed here + grep :[0-9]\{1,3\} .git/info/fast-import/remote-svn/svnsim.marks .git/info/fast-import/remote-svn/svnsim.marks.old + rm .git/info/fast-import/remote-svn/svnsim.marks + git fetch svnsim + test_cmp .git/info/fast-import/remote-svn/svnsim.marks.old .git/info/fast-import/remote-svn/svnsim.marks +' Could these loong lines be made a bit more manageable? It is getting extremely hard to follow. +test_expect_success REMOTE_SVN 'incremental imports must lead to the same head' ' + export SVNRMAX=3 + init_git + git fetch svnsim + test_cmp .git/refs/svn/svnsim/master .git/refs/remotes/svnsim/master + unset SVNRMAX + git fetch svnsim + test_cmp master.good .git/refs/remotes/svnsim/master +' + +test_debug 'git branch -a' + +test_done -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 7/8] http: factor out http error code handling
Jeff King p...@peff.net writes: Most of our http requests go through the http_request() interface, which does some nice post-processing on the results. In particular, it handles prompting for missing credentials as well as approving and rejecting valid or invalid credentials. Unfortunately, it only handles GET requests. Making it handle POSTs would be quite complex, so let's pull result handling code into its own function so that it can be reused from the POST code paths. Signed-off-by: Jeff King p...@peff.net --- http.c | 51 --- http.h | 1 + 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/http.c b/http.c index b61ac85..6793137 100644 --- a/http.c +++ b/http.c @@ -745,6 +745,33 @@ char *get_remote_object_url(const char *url, const char *hex, return strbuf_detach(buf, NULL); } +int handle_curl_result(struct active_request_slot *slot) +{ + struct slot_results *results = slot-results; + + if (results-curl_result == CURLE_OK) { + credential_approve(http_auth); + return HTTP_OK; + } else if (missing_target(results)) +... + return HTTP_ERROR; + } +} + @@ -820,9 +828,6 @@ static int http_request(const char *url, void *result, int target, int options) curl_slist_free_all(headers); strbuf_release(buf); - if (ret == HTTP_OK) - credential_approve(http_auth); OK, now this is part of handle_curl_result() so the caller does not have to worry about it, which is nice ;-) return ret; } -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: diff/merge tool that ignores whitespace changes
- Original Message - From: Matthew Caron matt.ca...@redlion.net Sent: Tuesday, August 28, 2012 1:41:51 PM Subject: Re: diff/merge tool that ignores whitespace changes I'm looking for a diff / merge tool that treats lines with only whitespace changes (trailing or leading whitespaces, linefeeds, etc) as equal. The goal is to make reviews as well as merging or rebasing easier when things like indentions often change. Does anybody know an solution for that ? I'm fond of Meld. I loved Meld when I was working exclusively on Linux several years ago. Honestly I think I set up my kdiff fonts/highlight colors/etc. to be very Meld-like (unintentionally, just what looked right). Looking at the website, technically Meld should build/run on a variety of OSes, but at some point (lost to the sands of time) I ran into trouble which is why I switched. Stephen -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC v2 PATCH] Teach rm to remove submodules unless they contain a git directory
Am 27.08.2012 22:59, schrieb Junio C Hamano: Jens Lehmann jens.lehm...@web.de writes: +{ +int i; +int errs = 0; + +for (i = 0; i list.nr; i++) { +const char *name = list.entry[i].name; +int pos; +struct cache_entry *ce; +struct stat st; + +pos = cache_name_pos(name, strlen(name)); +if (pos 0) +continue; /* ignore unmerged entry */ Would this cause git rm -f path for an unmerged submodule bypass the safety check? Oops, thanks for spotting that. So replacing the continue; with pos = -pos-1; should do the trick here, right? Will add some tests for unmerged submodules ... +ce = active_cache[pos]; + +if (!S_ISGITLINK(ce-ce_mode) || +(lstat(ce-name, st) 0) || +is_empty_dir(name)) +continue; + +if (!submodule_uses_gitfile(name)) +errs = error(_(submodule '%s' (or one of its nested + submodules) uses a .git directory\n + (use 'rm -rf' if you really want to remove + it including all of its history)), name); +} + +return errs; +} The call to this function comes at the very end and gives us yes/no for the entire set of paths. After getting this error for one submodule and bunch of other non-submodule paths, what is the procedure for the user to remove it that we want to recommend in our documentation? Would it go like this? $ git rm path1 path2 sub path3 ... get the above error ... $ git submodule --to-gitfile sub $ rm -fr sub $ git rm sub ... then finally ... $ git rm path1 path2 path3 With current git I'd recommend: $ git rm path1 path2 sub path3 ... get the above error ... $ rm -fr sub ... try again ... $ git rm path1 path2 sub path3 Maybe I should add the hint to repeat the git rm after removing the submodule to the error output? Once we implemented git submodule --to-gitfile it could be used instead of rm -fr sub to preserve the submodule's repo if the user wants to. BTW: I added the same message twice, here for the forced case and in check_local_mod() when not forced. Is there a recommended way to assign a localized message to a static variable, so I could define it only once and reuse it? @@ -80,8 +116,11 @@ static int check_local_mod(unsigned char *head, int index_only) /* * Is the index different from the file in the work tree? + * If it's a submodule, is its work tree modified? */ -if (ce_match_stat(ce, st, 0)) +if (ce_match_stat(ce, st, 0) || +(S_ISGITLINK(ce-ce_mode) + !ok_to_remove_submodule(ce-name))) local_changes = 1; As noted before, because we also skip these does it match the index? does it match the HEAD? checks for unmerged paths in this function, a submodule that has local changes or new files is eligible for removal during a conflicted merge. I have a feeling that this should be tightened a bit; wouldn't we want to check at least in the checked out version (i.e. stage #2 in the index) if the path were a submodule, even if we are in the middle of a conflicted merge? After all, the top level merge shouldn't have touched the submodule working tree, so the local modes and new files must have come from the end user action that was done _before_ the conflicted merge started, and not expendable, no? Right, I'll change that. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: libgit2 status
d...@cray.com writes: Nicolas Sebrecht nicolas.s@gmx.fr writes: Do you expect one big merge of a very stable libgit2 at some point? I don't think there's any need to merge libgit2 into the git project source. As a library, it should be perfectly usable as a project of its own, just like libcurl and libz. Otherwise, what about going with this optionnal LDFLAGS += -libgit2 ASAP with good disclaimer that it's only intended for development and testing purpose? Then, git-core could slowly rely on functions of libgit2, one after the other. This makes a lot of sense to me. As I already said in my earlier message in $gmane/204305, I wouldn't be surprised if some core stuff gets reimplemented on top of libgit2 and distributed as part of the git-core. But at this moment, I see that just as a blip of possibility far in the future. It would most likely start slowly, by adding lg-client/cat-file.c that is linked with libgit2 when make USE_LIBGIT2=YesPlease was asked for, and we compile the tried-and-true builtin/cat-file.c otherwise (cat-file may actually not the most trivial first step, though, but I think readers get the idea). Even after most if not all commands have counterparts reimplemented on libgit2, I do not think we can afford to drop any of the original for a long time. For that to happen, at the very least: - libgit2 must be available in major distros so that people can say [yum|apt-get] install libgit2-dev; and - the version of it packaged for major distros are recent and stable enough, so that we never have to say distro X ships with libgit2 that is too old, so people on that distro have to compile it from the source. which is the quality we expect from libraries we would depend on, like -lz, -lcurl, etc. It is OK if we have to conditionally compile out some of our code in the periphery when libgit2 that is available on the platform is too old (we allow it for -lcurl already). But all of the above assumes one thing: the reimplementated result does not suck ;-) which is a large unknown. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
GC of alternate object store (was: Bringing a bit more sanity to $GIT_DIR/objects/info/alternates?)
Oswald Buddenhagen wrote: (...)so the second approach is the bare aggregator repo which adds all other repos as remotes, and the other repos link back via alternates. problems: - to actually share objects, one always needs to push to the aggregator Run a cron job which frequently does that? - tags having a shared namespace doesn't actually work, because the repos have the same tags on different commits (they are independent repos, after all) Junio's proposal partially fixes that: It pushes refs/* instead of refs/heads/*, to refs/remotes/borrowing repo/. However... - one still cannot safely garbage-collect the aggregator, as the refs don't include the stashes and the index, so rebasing may invalidate these more transient objects. Also if you copy a repo (e.g. making a backup) instead of cloning it, and then start using both, they'll push into the same namespace - overwriting each other's refs. Non-fast-forward pushes can thus lose refs to objects needed by the other repo. receive.denyNonFastForwards only rejects pushes to refs/heads/ or something. (A feature, as I learned when I reported it as bug:-) IIRC Git has no config option to reject all non-fast-forward pushes. i would re-propose hallvard's volatile alternates (at least i think that's what he was talking about two weeks ago): they can be used to obtain objects, but every object which is in any way referenced from the current clone must be available locally (or from a regular alternate). that means that diffing, etc. would get objects only temporarily, while cherry-picking would actually copy (some of) the objects. this would make it possible to cross-link repositories, safely and without any 3rd parties. I'm afraid that idea by itself won't work:-( Either you borrow from a store or not. If Git uses an object from the volatile store, it can't always know if the caller needs the object to be copied. OTOH volatile stores which you do *not* borrow from would be useful: Let fetch/repack/gc/whatever copy missing objects from there. 2nd attempt for a way to gc of the alternate repo: Copy the with removed objects into each borrowing repo, then gc them. Like this: 1. gc, but pack all to-be-removed objects into a removable pack. 2. Hardlink/copy the removable pack - with a .keep file - into borrowing repos when feasible: I.e. repos you can find and have write access to. Update their .git/objects/info/packs. (Is there a Git command for this?) Repeat until nothing to do, in case someone created a new repo during this step. 3. Move the pack from the alternate repo to a backup object store which will keep it for a while. 4. Delete the .keep files from step (2). They were needed in case a user gc'ed away an object from the pack and then added an identical object - borrowed from the to-be-removed pack. 5. gc/repack the other repos at your leisure. 666. Repos you could not update in step (2), can get temporarily broken. Their owners must link the pack from the backup store by hand, or use that store as a volatile store and then gc/repack. Loose objects are a problem: If a repo has longer expiry time(s) than the alternate store, it will get loads of loose objects from all repos which push into the alternate store. Worse, gc can *unpack* those objects, consuming a lot of space. See threads git gc == git garbage-create from removed branch (3 May) and Keeping unreachable objects in a separate pack instead of loose? (10 Jun). Presumably the work-arounds are: - Use long expiry times in the alternate repo. I don't know which expiration config settings are relevant how. - Add some command which checks and warns if the repo has longer expiry time than the repo it borrows from. Also I hope Git will be changed to instead pack such loose objects somewhere, as discussed in the above threads. All in all, this isn't something you'd want to do every day. But it looks doable and can be scripted. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: git checkout -t -B
From: Junio C Hamano gits...@pobox.com Sent: Tuesday, August 28, 2012 12:22 AM Philip Oakley philipoak...@iee.org writes: I searched for all occurrences of '[[' which would indicate a double optional argument within the synopsis and only found git-read-tree. Double-optional? That is not an issue. For clarification, I was picking out the particular case that I saw in the git checkout syntax of an option (which necessarily starts with a first `[` ) which is actually then a multi-choice option, so has a second '[' for that, and then has the required parameter after the closing ']' of the multi-choice, then another ']' after the parameter - hence my 'double optional argument' statement. It was the multi-choice option, with parameter case that I was looking for, as that multi-choice part would be easy to confuse with the normal list of many options. If an option always takes a parameter, we would have git cmd [--option parameter] instead of one of git cmd [--option] git cmd [--option] parameter git cmd [--option] parameter... and if we had --option:: This option distims the parameter ... that needs to be updated to --option parameter:: This option distims the parameter ... Agreed. Philip -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] Support for setitimer() on platforms lacking it
Joachim Schmitz j...@schmitz-digital.de writes: Implementation includes getitimer(), but for now it is static. Supports ITIMER_REAL only. Signed-off-by: Joachim Schmitz j...@schmitz-digital.de --- May need a header file for ITIMER_*, struct itimerval and the prototypes, But for now, and the HP NonStop platform this isn't needed, here sys/time has ITIMER_* and struct timeval, and the prototypes can vo into git-compat-util.h for now (Patch 2/2) compat/itimer.c | 50 ++ 1 file changed, 50 insertions(+) create mode 100644 compat/itimer.c diff --git a/compat/itimer.c b/compat/itimer.c new file mode 100644 index 000..713f1ff --- /dev/null +++ b/compat/itimer.c @@ -0,0 +1,50 @@ +#include ../git-compat-util.h + +static int git_getitimer(int which, struct itimerval *value) +{ + int ret = 0; + + switch (which) { + case ITIMER_REAL: + value-it_value.tv_usec = 0; + value-it_value.tv_sec = alarm(0); + ret = 0; /* if alarm() fails, we get a SIGLIMIT */ + break; + case ITIMER_VIRTUAL: /* FALLTHRU */ + case ITIMER_PROF: errno = ENOTSUP; ret = -1; break; + default: errno = EINVAL; ret = -1; + } Just a style thing, but we align case arms and switch statements, like this: switch (which) { case ...: stmt; break; default: stmt; break; } Because alarm() runs in integral seconds granularity, this could return 0.0 sec (i.e. do not re-trigger this alarm any more) in ovalue after setting alarm(1) (via git_setitimer()) and calling this function (via git_setitimer() again) before the timer expires, no? Is it a desired behaviour? What I am most worried about is that callers _might_ take this emulation too seriously, grab the remainder from getitimer(), and drives a future call to getitimer() with the returned value, and accidentally cause the recurring nature of the request to be disabled. I see no existing code calls setitimer() with non-NULL ovalue, and I do not think we would add a new caller that would do so in any time soon, so it may not be a bad idea to drop support of returning the remaining timer altogether from this emulation layer (just like giving anything other than ITIMER_REAL gives us ENOTSUP). That would sidestep the whole we cannot answer how many milliseconds are still remaining on the timer when using emulation based on alarm(). +int git_setitimer(int which, const struct itimerval *value, + struct itimerval *ovalue) +{ + int ret = 0; + + if (!value + || value-it_value.tv_usec 0 + || value-it_value.tv_usec 100 + || value-it_value.tv_sec 0) { + errno = EINVAL; + return -1; + } + + else if (ovalue) + if (!git_getitimer(which, ovalue)) + return -1; /* errno set in git_getitimer() */ + + else + switch (which) { + case ITIMER_REAL: + alarm(value-it_value.tv_sec + + (value-it_value.tv_usec 0) ? 1 : 0); Why is this capped to 1 second? Is this because no existing code uses the timer for anything other than 1 second or shorter? If that is the case, that needs at least some documenting (or a possibly support for longer expiration, if it is not too cumbersome to add). + ret = 0; /* if alarm() fails, we get a SIGLIMIT */ + break; + case ITIMER_VIRTUAL: /* FALLTHRU */ + case ITIMER_PROF: errno = ENOTSUP; ret = -1; break; Please don't add a misleading fallthru label here. We do not say fallthru when two case arms do _exactly_ the same thing. Only when the one arm does some pre-action before the common action, i.e. switch (which) { case one: do some thing specific to one; /* fallthru */ case two: do some thing common between one and two; break; } we label it fallthru to make it clear to the readers that it is not missing a break but is deliberate. + default: errno = EINVAL; ret = -1; + } + + return ret; +} Thanks. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/3] checkout: reorder option handling
Nguyễn Thái Ngọc Duy pclo...@gmail.com writes: checkout operates in three different modes. On top of that it tries to be smart by guessing the branch name for switching. This results in messy option handling code. This patch reorders it so: - easy option handling comes first - the big chunk of branch name guessing comes next - mode detection comes last. Once the mode is known, check again to see if users specify any incompatible options - the actual action is done Another slight improvement is always print branch name (or commit name) when printing errors related ot them. This helps catch the case where an option is mistaken as branch/commit. Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com --- ... + /* Easy mode-independent incompatible checks */ if (opts.force_detach (opts.new_branch || opts.new_orphan_branch)) die(_(--detach cannot be used with -b/-B/--orphan)); Did you catch --detach -B combination without checking new_branch_force? if (opts.force_detach 0 opts.track) die(_(--detach cannot be used with -t)); + if (opts.force opts.merge) + die(_(git checkout: -f and -m are incompatible)); + + if (conflict_style) { + opts.merge = 1; /* implied */ + git_xmerge_config(merge.conflictstyle, conflict_style, NULL); + } checkout --conflict=diff3 -f branch would imply combination of -m and -f, which is supposed to be forbidden in the previous check, no? I very much like the idea of separating things in phases like your proposed log message explains. But I wonder if the order should be to do dwimming and parameter canonicalization first, then decide the mode (these might have to be swapped, as the same parameter may dwim down to different things depending on the mode), and finally check for sanity before performing. To avoid confusion, it also might not be a bad idea to remove new_branch_force and new_orphan_branch from the structure and introduce enum branch_creation_type or something, and always have the new branch name in new_branch field (this needs to get various pointers into opts out of the parseopt options[] array; parse into separate variables and decide what to put in struct checkout_opts), independent from how that branch is going to be created (either -b, -B, or --orphan). -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH/RFC] Add gui.displayuntracked option
When git is used to track only a subset of a directory, or there is no sure way to divide files to ignore from files to track, git user have to live with large number of untracked files. These files present in file list, and should always be scrolled through to handle real changes. Situation can become even worse, then number of the untracked files grows above the maxfilesdisplayed limit. In the case, even staged files can be hidden by git-gui. This change introduces new configuration variable gui.displayuntracked, which, when set to false, instructs git-gui not to show untracked files in files list. They can be staged from commandline or other tools (like IDE of file manager), then they become visible. Default value of the option is true, which is compatible with current behavior. Signed-off-by: Max Kirillov m...@max630.net --- git-gui/git-gui.sh | 14 ++ git-gui/lib/option.tcl |1 + 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/git-gui/git-gui.sh b/git-gui/git-gui.sh index ba4e5c1..504fc4a 100755 --- a/git-gui/git-gui.sh +++ b/git-gui/git-gui.sh @@ -897,6 +897,7 @@ set font_descs { {fontdiff font_diff {mc Diff/Console Font}} } set default_config(gui.stageuntracked) ask +set default_config(gui.displayuntracked) true ## ## @@ -1535,18 +1536,23 @@ proc rescan_stage2 {fd after} { set buf_rdf {} set buf_rlo {} - set rescan_active 3 + set rescan_active 2 ui_status [mc Scanning for modified files ...] set fd_di [git_read diff-index --cached -z [PARENT]] set fd_df [git_read diff-files -z] - set fd_lo [eval git_read ls-files --others -z $ls_others] fconfigure $fd_di -blocking 0 -translation binary -encoding binary fconfigure $fd_df -blocking 0 -translation binary -encoding binary - fconfigure $fd_lo -blocking 0 -translation binary -encoding binary + fileevent $fd_di readable [list read_diff_index $fd_di $after] fileevent $fd_df readable [list read_diff_files $fd_df $after] - fileevent $fd_lo readable [list read_ls_others $fd_lo $after] + + if {[is_config_true gui.displayuntracked]} { + set fd_lo [eval git_read ls-files --others -z $ls_others] + fconfigure $fd_lo -blocking 0 -translation binary -encoding binary + fileevent $fd_lo readable [list read_ls_others $fd_lo $after] + incr rescan_active + } } proc load_message {file} { diff --git a/git-gui/lib/option.tcl b/git-gui/lib/option.tcl index 0cf1da1..2177db6 100644 --- a/git-gui/lib/option.tcl +++ b/git-gui/lib/option.tcl @@ -159,6 +159,7 @@ proc do_options {} { {c gui.encoding {mc Default File Contents Encoding}} {b gui.warndetachedcommit {mc Warn before committing to a detached head}} {s gui.stageuntracked {mc Staging of untracked files} {list yes no ask}} + {b gui.displayuntracked {mc Show untracked files}} } { set type [lindex $option 0] set name [lindex $option 1] -- 1.7.9.1 -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 5/5] (BROKEN) get_merge_bases_many(): walk from many tips in parallel
Junio C Hamano gits...@pobox.com writes: Junio C Hamano gits...@pobox.com writes: for (i = 0; i cnt; i++) { -if (rslt[i]) +/* + * Is rslt[i] an ancestor of any of the others? + * then it is not interesting to us. + */ +for (j = 0; j i; j++) +others[j] = rslt[j]; +for (j = 1 + 1; j cnt; j++) s/1 + 1/i + 1/; With that, all tests seem to pass ;-) git merge-base itself seems to have more room for improvement. Trying to recompute bases for recent 200 merges in the kernel history with the attached script does not show any improvement with or without the series on top of recent master. Correctnesswise it seems to be OK, though---I get byte-for-byte identical output. -- 8 -- #!/bin/sh git rev-list --committer=torva...@linux-foundation.org \ --max-parents=2 --min-parents=2 --parents v3.5..v3.6-rc2 RL cmd=' while read result parent1 parent2 do $GIT merge-base $parent1 $parent2 done RL ' GIT=rungit master time sh -c $cmd :stock GIT=../git.git/git time sh -c $cmd :optim cmp :stock :optim -- 8 -- -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
git-rerere vs rebase --skip
Hi, In one of my workflows, I constantly rebase topic branches on top of new upstream imports. As there are several upstream import branches, I have similar topic branches on top of different imports. When rebasing the topic branches, I can hit conflict resolution that I already had to do for other topic branches on another upstream import branch. Here, git rerere is very helpful. But sometimes, the conflict resolution is just to skip the patch, because it was incorporated upstream in a way that git doesn't detect, or it was obsoleted, or whatever. In such cases, git rerere is not being helpful because it doesn't store any information about that, and I have to check again if that's an actual conflict to solve or a patch to skip again. It would be helpful if there was a rebase --skip mode that would tell rerere to record that the resolution *is* --skip. Mike -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: I think git show is broken
Jeff King p...@peff.net writes: Yes, that is what's going on. But it's still a regression. There was some discussion of what --quiet should do here: http://thread.gmane.org/gmane.comp.version-control.git/171357 which resulted in a patch that took away --quiet. But then this thread: http://thread.gmane.org/gmane.comp.version-control.git/174665 resulted in restoring it as a synonym for -s. Unfortunately there's a bug in that fix, which you are seeing. Patch is below. Thanks for digging this through to the bottom. ... However, that commit did not fix it in all cases. It sets the flag after setup_revisions is called. Naively, this makes sense because you would expect the setup_revisions parser to overwrite our output format flag if -p or another output format flag is seen. However, that is not how the NO_OUTPUT flag works. We actually store it in the bit-field as just another format. At the end of setup_revisions, we call diff_setup_done, which post-processes the bitfield and clears any other formats if we have set NO_OUTPUT. By setting the flag after setup_revisions is done, diff_setup_done does not have a chance to make this tweak, and we end up with other format options still set. As a result, the flag would have no effect in git log -p --quiet or git show --quiet. Fix it by setting the format flag before the call to setup_revisions. This also means that git show --name-status --quiet will start erroring out, if I am not recalling what diff_setup_done() does. Which pretty much means --quiet given to the log family is truly a synonym to -s, as the error condition that triggers is exactly the same for this: git show --name-status -s which is fine, I think. Signed-off-by: Jeff King p...@peff.net --- builtin/log.c | 2 +- t/t7007-show.sh | 12 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/builtin/log.c b/builtin/log.c index ecc2793..c22469c 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -109,9 +109,9 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix, PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN | PARSE_OPT_KEEP_DASHDASH); - argc = setup_revisions(argc, argv, rev, opt); if (quiet) rev-diffopt.output_format |= DIFF_FORMAT_NO_OUTPUT; + argc = setup_revisions(argc, argv, rev, opt); /* Any arguments at this point are not recognized */ if (argc 1) diff --git a/t/t7007-show.sh b/t/t7007-show.sh index a40cd36..e41fa00 100755 --- a/t/t7007-show.sh +++ b/t/t7007-show.sh @@ -108,4 +108,16 @@ test_expect_success 'showing range' ' test_cmp expect actual.filtered ' +test_expect_success '-s suppresses diff' ' + echo main3 expect + git show -s --format=%s main3 actual + test_cmp expect actual +' + +test_expect_success '--quiet suppresses diff' ' + echo main3 expect + git show --quiet --format=%s main3 actual + test_cmp expect actual +' + test_done -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: I think git show is broken
On Tue, Aug 28, 2012 at 03:36:26PM -0700, Junio C Hamano wrote: As a result, the flag would have no effect in git log -p --quiet or git show --quiet. Fix it by setting the format flag before the call to setup_revisions. This also means that git show --name-status --quiet will start erroring out, if I am not recalling what diff_setup_done() does. Which pretty much means --quiet given to the log family is truly a synonym to -s, as the error condition that triggers is exactly the same for this: git show --name-status -s which is fine, I think. Yes, I noticed that. I think it is fine for --quiet to be a true synonym for -s here. Though I am puzzled why we would error out on --name-status -s but not --patch -s. What is the difference between --name-status and --patch here? Shouldn't -s override all formatting options? And one final thing I noticed that is probably not worth the trouble to fix: the position of -s is independent of its effect. Normally options which override each other would be position dependent, so: git log --relative-date --date=local and git log --date=local --relative-date would both throw away the first option and let the latter take effect. But doing: git log --patch -s and git log -s --patch will always have -s take over. I don't think it's a huge deal, and fixing it would be a pain. We'd have to take NO_OUTPUT out of the bit-field and make it a special option, and fix any callers who try to be clever about recognizing NO_OUTPUT as a specifically-given option. And then for --quiet, we'd have to handle it at its proper spot on the command-line, which would mean converting log's parse-options invocation to be step-wise. Probably not worth it for a minor bit of consistency that nobody has actually complained about. -Peff -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: git-rerere vs rebase --skip
Mike Hommey m...@glandium.org writes: When rebasing the topic branches, I can hit conflict resolution that I already had to do for other topic branches on another upstream import branch. Here, git rerere is very helpful. But sometimes, the conflict resolution is just to skip the patch, because it was incorporated upstream in a way that git doesn't detect, or it was obsoleted, or whatever. In such cases, git rerere is not being helpful because it doesn't store any information about that, and I have to check again if that's an actual conflict to solve or a patch to skip again. It would be helpful if there was a rebase --skip mode that would tell rerere to record that the resolution *is* --skip. That is like saying my hammer is very helpful when I want to hit nails, but sometimes I wish it helped me with screws. The only thing rerere does is to remember the shape of the conflicted state and desired resolution _per_ _file_. It does not tell rebase what to do next (you do, via git add -u followed by git rebase --continue). Presumably, you _could_ run git checkout HEAD $path followed by git rerere to record that a particular shape of the conflicted state should resolve to what you already have in the HEAD commit, so that the same conflict that happens in future rebases automatically resolve to a no-op for these conflicted paths, and telling rebase to continue via the same add -u rebase --continue might notice that there is no change, and its skip empty logic might kick in. But I wouldn't blindly recommend it. If a change you are replaying has two paths, one that somehow cleanly merges, and the other that conflicts because you do have an equivalent change (and more) in the updated HEAD, letting rebase continue that way would record only the changes to the first path while ignoring the other one, which may or may not be what you want. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 5/5] (BROKEN) get_merge_bases_many(): walk from many tips in parallel
Junio C Hamano gits...@pobox.com writes: Junio C Hamano gits...@pobox.com writes: Junio C Hamano gits...@pobox.com writes: for (i = 0; i cnt; i++) { - if (rslt[i]) + /* +* Is rslt[i] an ancestor of any of the others? +* then it is not interesting to us. +*/ + for (j = 0; j i; j++) + others[j] = rslt[j]; + for (j = 1 + 1; j cnt; j++) s/1 + 1/i + 1/; With that, all tests seem to pass ;-) git merge-base itself seems to have more room for improvement. Trying to recompute bases for recent 200 merges in the kernel history with the attached script does not show any improvement with or without the series on top of recent master. Correctnesswise it seems to be OK, though---I get byte-for-byte identical output. -- 8 -- #!/bin/sh git rev-list --committer=torva...@linux-foundation.org \ --max-parents=2 --min-parents=2 --parents v3.5..v3.6-rc2 RL cmd=' while read result parent1 parent2 do $GIT merge-base $parent1 $parent2 done RL ' GIT=rungit master time sh -c $cmd :stock GIT=../git.git/git time sh -c $cmd :optim cmp :stock :optim -- 8 -- I have this suspicion that it is spending most of its time in insert-by-date. Luckily, merge_bases_many() is totally outside of the usual revision traversal and its use of the commit list is pretty well isolated. Peff, can I interest you into resurrecting your $gmane/174007 and $gmane/174008 (we do not need pop_commit_from_queue() in the latter; everything can stay as static to commit.c for now) to see how well priority queue based approach would perform? -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] test: set the realpath of CWD as TRASH_DIRECTORY
On 08/27/2012 06:15 PM, Junio C Hamano wrote: Jiang Xin worldhello@gmail.com writes: Some testcases will fail if current work directory is on a symlink. symlink$ sh ./t4035-diff-quiet.sh $ sh ./t4035-diff-quiet.sh --root=/symlink $ TEST_OUTPUT_DIRECTORY=/symlink sh ./t4035-diff-quiet.sh This is because the realpath of .git directory will be returned when running the command 'git rev-parse --git-dir' in a subdir of the work tree, and the realpath may not equal to $TRASH_DIRECTORY. In this fix, $TRASH_DIRECTORY is determined right after the realpath of CWD is resolved. Signed-off-by: Jiang Xin worldhello@gmail.com Reported-by: Michael Haggerty mhag...@alum.mit.edu Signed-off-by: Jiang Xin worldhello@gmail.com --- I think this is in line with what was discussed in the other thread Michael brought this up. Thanks for following it through. Michael, this looks good to me; anything I missed? I can confirm that this patch eliminates the test failures that I was seeing in t4035 and t9903. But it also changes almost 600 *other* tests from succeed even in the presence of symlinks to never tested in the presence of symlinks, and I think that is surrendering more ground than necessary. I would rather see one of the following approaches: *If* the official policy is that GIT_CEILING_DIRECTORIES is not reliable in the presence of symlinks, then (a) that limitation should be mentioned in the documentation; (b) the affected tests should either be skipped in the case of symlinked directories or they (alone!) should take measures to work around the problem. *If* the official policy is that GIT_CEILING_DIRECTORIES should work in the presence of symlinks, then (a) we should add a failing test case that specifically documents this bug; (b) other tests that fail as a side effect of this bug even though they are trying to test something else should either be skipped in the case of symlinked directories or they (alone!) should take measures to work around the problem; (c) the bug should be fixed as soon as possible. In fact, we could even go further: * The cd -P in test-lib.sh could be changed to cd -L, to avoid masking other problems related to symlinks. If I make that change, I get test failures in 10 files when using --root=/symlinkeddir, and not all of them are obviously related to GIT_CEILING_DIRECTORIES. Some of these might simply be sloppiness in how the test scripts are written, but others might be bugs in git proper. * We could *intentionally* access the trash directories via a symlink on systems that support symlinks (much like the trash directory names intentionally include a space) to get *systematic* test coverage of symlink issues, rather than occasional testing and mysterious failures when somebody happens to have a symlink in his build path or root. (But it is still the case that I don't have time to work on this.) Michael -- Michael Haggerty mhag...@alum.mit.edu http://softwareswirl.blogspot.com/ -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Funny 'git describe --contains' output
Hi, In the Linux kernel tree, commit 0136db586c028f71e7cc21cc183064ff0d5919 is a bit odd. If I go to look to see what release it was in, I normally do: $ git describe --contains 0136db586c028f71e7cc21cc183064ff0d5919 v3.6-rc1~59^2~56^2~76 However, it really showed up first in the 3.5-rc1 kernel release, as can be seen by doing the following: $ git tag --contains 0136db586c028f71e7cc21cc183064ff0d5919 v3.5 v3.5-rc1 v3.5-rc2 v3.5-rc3 v3.5-rc4 v3.5-rc5 v3.5-rc6 v3.5-rc7 v3.6-rc1 v3.6-rc2 v3.6-rc3 This commit ended up coming into Linus's tree in two different places, both in 3.5-rc1 and in 3.6-rc1, through different merge requests, so it seems to be tricky to figure out when it first went in. Asking Linus about this, he tried the following: $ git name-rev --tags 0136db586c028f71e7cc21cc183064ff0d5919 0136db586c028f71e7cc21cc183064ff0d5919 tags/v3.6-rc1~59^2~56^2~76 $ git rev-list 0136db586c028f71e7cc21cc183064ff0d5919..v3.5-rc1 | wc 11415 11415 468015 $ git rev-list 0136db586c028f71e7cc21cc183064ff0d5919..v3.4-rc1 | wc 0 0 0 $ git rev-list 0136db586c028f71e7cc21cc183064ff0d5919..v3.6-rc1 | wc 22279 22279 913439 which shows that there are less commits to get from this commit to v3.5-rc1 instead of v3.6-rc1, so something odd is going on here. Any ideas? I can reproduce this right now with git version 1.7.12.116.g31e0100 thanks, greg k-h -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Funny 'git describe --contains' output
Greg KH gre...@linuxfoundation.org writes: In the Linux kernel tree, commit 0136db586c028f71e7cc21cc183064ff0d5919 is a bit odd. If I go to look to see what release it was in, I normally do: $ git describe --contains 0136db586c028f71e7cc21cc183064ff0d5919 v3.6-rc1~59^2~56^2~76 ... Any ideas? That is 59 + 1 + 56 + 1 + 76 = 193 steps away from the tag v3.6-rc1. $ git name-rev --refs=refs/tags/v3.5-rc1 0136db58 0136db58 tags/v3.5-rc1~83^2~81^2~76 which is 83 + 1 + 81 + 1 + 76 = 242 steps away from that tag. So it _is_ odd that the newly tagged tip merged a branch that had smaller development since it merged the commit, but name-rev seems to be measuring the steps it takes from the tags to reach the commit and giving us the one that gives the shortest path correctly. Obviously, that is not the same as which tag is the oldest one among the ones that can reach this commit? -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html