Re: [PATCH v6 09/10] replace: check mergetags when using --graft

2014-07-07 Thread Christian Couder
From: Junio C Hamano 
>
> Christian Couder  writes:
> 
>> When using --graft, with a mergetag in the original
>> commit, we should check that the commit pointed to by
>> the mergetag is still a parent of then new commit we
>> create, otherwise the mergetag could be misleading.
>>
>> If the commit pointed to by the mergetag is no more
>> a parent of the new commit, we could remove the
>> mergetag, but in this case there is a good chance
>> that the title or other elements of the commit might
>> also be misleading. So let's just error out and
>> suggest to use --edit instead on the commit.
> 
> I do not quite understand the reasoning.  If you have a merge you
> earlier made with a signed tag, and then want to redo the merge with
> an updated tip of that branch (perhaps the side branch was earlier
> based on maint but now was rebased on master), it will perfectly be
> normal to expect that the title or other elements of the resulting
> merge to stay the same.  

Yeah, but then you might also want to have a mergetag for the updated
tip of the branch and --graft will not put it in the new commit, so it
would be better to use --edit in this case.

> Why is it a good idea to error it out?

Because sometimes, in complex cases, it is misleading to do as if you
can do the right thing, when there is a good chance you cannot.

> If the argument were '"replace --graft" that changes the parents is
> likely to affect merge summary message, so error out and suggest to
> use --edit instead', regardless of the 'mergetag', I'd understand
> it, but that would essentially mean that 'replace --graft' should
> never be used, so...

I think that when "replace --graft" is used on a regular commit there
is much better chance that the resulting replacement commit will be as
the user expect it to be.

Thanks,
Christian.
--
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 v6 09/10] replace: check mergetags when using --graft

2014-07-07 Thread Junio C Hamano
Christian Couder  writes:

> When using --graft, with a mergetag in the original
> commit, we should check that the commit pointed to by
> the mergetag is still a parent of then new commit we
> create, otherwise the mergetag could be misleading.
>
> If the commit pointed to by the mergetag is no more
> a parent of the new commit, we could remove the
> mergetag, but in this case there is a good chance
> that the title or other elements of the commit might
> also be misleading. So let's just error out and
> suggest to use --edit instead on the commit.

I do not quite understand the reasoning.  If you have a merge you
earlier made with a signed tag, and then want to redo the merge with
an updated tip of that branch (perhaps the side branch was earlier
based on maint but now was rebased on master), it will perfectly be
normal to expect that the title or other elements of the resulting
merge to stay the same.  Why is it a good idea to error it out?

If the argument were '"replace --graft" that changes the parents is
likely to affect merge summary message, so error out and suggest to
use --edit instead', regardless of the 'mergetag', I'd understand
it, but that would essentially mean that 'replace --graft' should
never be used, so...

--
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 v6 09/10] replace: check mergetags when using --graft

2014-07-06 Thread Christian Couder
When using --graft, with a mergetag in the original
commit, we should check that the commit pointed to by
the mergetag is still a parent of then new commit we
create, otherwise the mergetag could be misleading.

If the commit pointed to by the mergetag is no more
a parent of the new commit, we could remove the
mergetag, but in this case there is a good chance
that the title or other elements of the commit might
also be misleading. So let's just error out and
suggest to use --edit instead on the commit.

Signed-off-by: Christian Couder 
---
 builtin/replace.c | 47 +++
 1 file changed, 47 insertions(+)

diff --git a/builtin/replace.c b/builtin/replace.c
index cc29ef2..2290529 100644
--- a/builtin/replace.c
+++ b/builtin/replace.c
@@ -13,6 +13,7 @@
 #include "refs.h"
 #include "parse-options.h"
 #include "run-command.h"
+#include "tag.h"
 
 static const char * const git_replace_usage[] = {
N_("git replace [-f]  "),
@@ -325,6 +326,50 @@ static void replace_parents(struct strbuf *buf, int argc, 
const char **argv)
strbuf_release(&new_parents);
 }
 
+struct check_mergetag_data {
+   int argc;
+   const char **argv;
+};
+
+static void check_one_mergetag(struct commit *commit,
+  struct commit_extra_header *extra,
+  void *data)
+{
+   struct check_mergetag_data *mergetag_data = (struct check_mergetag_data 
*)data;
+   const char *ref = mergetag_data->argv[0];
+   unsigned char tag_sha1[20];
+   struct tag *tag;
+   int i;
+
+   hash_sha1_file(extra->value, extra->len, typename(OBJ_TAG), tag_sha1);
+   tag = lookup_tag(tag_sha1);
+   if (!tag)
+   die(_("bad mergetag in commit '%s'"), ref);
+   if (parse_tag_buffer(tag, extra->value, extra->len))
+   die(_("malformed mergetag in commit '%s'"), ref);
+
+   /* iterate over new parents */
+   for (i = 1; i < mergetag_data->argc; i++) {
+   unsigned char sha1[20];
+   if (get_sha1(mergetag_data->argv[i], sha1) < 0)
+   die(_("Not a valid object name: '%s'"), 
mergetag_data->argv[i]);
+   if (!hashcmp(tag->tagged->sha1, sha1))
+   return; /* found */
+   }
+
+   die(_("original commit '%s' contains mergetag '%s' that is discarded; "
+ "use --edit instead of --graft"), ref, sha1_to_hex(tag_sha1));
+}
+
+static void check_mergetags(struct commit *commit, int argc, const char **argv)
+{
+   struct check_mergetag_data mergetag_data;
+
+   mergetag_data.argc = argc;
+   mergetag_data.argv = argv;
+   for_each_mergetag(check_one_mergetag, commit, &mergetag_data);
+}
+
 static int create_graft(int argc, const char **argv, int force)
 {
unsigned char old[20], new[20];
@@ -349,6 +394,8 @@ static int create_graft(int argc, const char **argv, int 
force)
warning(_("the signature will be removed in the replacement 
commit!"));
}
 
+   check_mergetags(commit, argc, argv);
+
if (write_sha1_file(buf.buf, buf.len, commit_type, new))
die(_("could not write replacement commit for: '%s'"), old_ref);
 
-- 
2.0.0.421.g786a89d.dirty


--
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