[PATCH v4] merge: add a --signoff flag.

2017-07-26 Thread Łukasz Gryglicki
Some projects require every commit, even merges, to be signed off [*1*].
Because "git merge" does not have a "--signoff"
option like "git commit" does, the user needs to add one
manually when the command presents an editor to describe the
merge, or later use "git commit --amend --signoff".

Help developers of these projects by teaching "--signoff" option to "git merge".

*1*
https://public-inbox.org/git/CAHv71zK5SqbwrBFX=a8-dy9h3kt4feymgv__p2gzznr0wua...@mail.gmail.com/T/#u

Requested-by: Dan Kohn <d...@linuxfoundation.org>
Signed-off-by: Łukasz Gryglicki <lukaszgrygli...@o2.pl>
---
 Documentation/git-merge.txt |  8 +
 builtin/merge.c |  4 +++
 t/t7614-merge-signoff.sh| 88 +
 3 files changed, 100 insertions(+)
 create mode 100755 t/t7614-merge-signoff.sh

diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt
index 04fdd8cf086db..630cb4b7f90d7 100644
--- a/Documentation/git-merge.txt
+++ b/Documentation/git-merge.txt
@@ -64,6 +64,14 @@ OPTIONS
 ---
 include::merge-options.txt[]
 
+--signoff::
+   Add Signed-off-by line by the committer at the end of the commit
+   log message.  The meaning of a signoff depends on the project,
+   but it typically certifies that committer has
+   the rights to merge work under the same license and
+   agrees to a Developer Certificate of Origin
+   (see http://developercertificate.org/ for more information).
+
 -S[]::
 --gpg-sign[=]::
GPG-sign the resulting merge commit. The `keyid` argument is
diff --git a/builtin/merge.c b/builtin/merge.c
index 900bafdb45d0b..78c36e9bf353b 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -70,6 +70,7 @@ static int continue_current_merge;
 static int allow_unrelated_histories;
 static int show_progress = -1;
 static int default_to_upstream = 1;
+static int signoff;
 static const char *sign_commit;
 
 static struct strategy all_strategy[] = {
@@ -233,6 +234,7 @@ static struct option builtin_merge_options[] = {
{ OPTION_STRING, 'S', "gpg-sign", _commit, N_("key-id"),
  N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
OPT_BOOL(0, "overwrite-ignore", _ignore, N_("update ignored 
files (default)")),
+   OPT_BOOL(0, "signoff", , N_("add Signed-off-by:")),
OPT_END()
 };
 
@@ -763,6 +765,8 @@ static void prepare_to_commit(struct commit_list 
*remoteheads)
strbuf_addch(, '\n');
if (0 < option_edit)
strbuf_commented_addf(, _(merge_editor_comment), 
comment_line_char);
+   if (signoff)
+   append_signoff(, ignore_non_trailer(msg.buf, msg.len), 0);
write_file_buf(git_path_merge_msg(), msg.buf, msg.len);
if (run_commit_hook(0 < option_edit, get_index_file(), 
"prepare-commit-msg",
git_path_merge_msg(), "merge", NULL))
diff --git a/t/t7614-merge-signoff.sh b/t/t7614-merge-signoff.sh
new file mode 100755
index 0..823d840d423df
--- /dev/null
+++ b/t/t7614-merge-signoff.sh
@@ -0,0 +1,88 @@
+#!/bin/sh
+
+test_description='git merge --signoff
+
+This test runs git merge --signoff and makes sure that it works.
+'
+
+. ./test-lib.sh
+
+# Setup test files
+test_setup () {
+  # Expected commit message after merge --signoff
+  printf "Merge branch 'master' into other-branch\n\n" >expected-signed &&
+  printf "Signed-off-by: $(git var GIT_COMMITTER_IDENT | sed -e "s/>.*/>/")\n" 
>>expected-signed &&
+
+  # Expected commit message after merge without --signoff (or with 
--no-signoff)
+  echo "Merge branch 'master' into other-branch" >expected-unsigned &&
+
+  # Initial commit and feature branch to merge master into it.
+  git commit --allow-empty -m "Initial empty commit" &&
+  git checkout -b other-branch &&
+  test_commit other-branch file1 1
+}
+
+# Create fake editor that just copies file
+create_fake_editor () {
+  echo 'cp "$1" "$1.saved"' | write_script save-editor
+}
+
+test_expect_success 'setup' '
+  test_setup && create_fake_editor
+'
+
+test_expect_success 'git merge --signoff adds a sign-off line' '
+  git checkout master &&
+  test_commit master-branch-2 file2 2 &&
+  git checkout other-branch &&
+  git merge master --signoff --no-edit &&
+  git cat-file commit HEAD | sed -e "1,/^\$/d" >actual &&
+  test_cmp expected-signed actual
+'
+
+test_expect_success 'git merge does not add a sign-off line' '
+  git checkout master &&
+  test_commit master-branch-3 file3 3 &&
+  git checkout other-branch &&
+  git merge master --no-edit &&
+  git cat-file commit HEAD | sed -e "1,/^\$/d" &g

[PATCH v3] merge: add a --signoff flag.

2017-07-04 Thread Łukasz Gryglicki
Some projects require every commit to be signed off.
Our workflow is to create feature branches and require every commit to
be signed off. When feature is finally approved we need to merge it into
master. Merge itself is usually trivial and is done by
`git merge origin/master`.

Unfortunatelly `merge` command have no --signoff
flag, so we need to either add signoff line manually or use
`git commit --amend -s` after the merge.

First solution is not ideal because not all developers are familiar with
exact sign-off syntax. The second solution works, but is obviously tedious.

This patch adds --signoff support to `git-merge` command.
It works just like --signoff in `git-commit` command.

More details can be found here:
https://public-inbox.org/git/CAHv71zK5SqbwrBFX=a8-dy9h3kt4feymgv__p2gzznr0wua...@mail.gmail.com/T/#u

Signed-off-by: lukaszgryglicki 
---
 Documentation/git-merge.txt |  8 ++
 builtin/merge.c |  4 +++
 t/t7614-merge-signoff.sh| 69 +
 3 files changed, 81 insertions(+)
 create mode 100755 t/t7614-merge-signoff.sh

diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt
index 04fdd8cf086db..6b308ab6d0b52 100644
--- a/Documentation/git-merge.txt
+++ b/Documentation/git-merge.txt
@@ -64,6 +64,14 @@ OPTIONS
 ---
 include::merge-options.txt[]
 
+--signoff::
+   Add Signed-off-by line by the committer at the end of the commit
+   log message.  The meaning of a signoff depends on the project,
+   but it typically certifies that committer has
+   the rights to submit this work under the same license and
+   agrees to a Developer Certificate of Origin
+   (see http://developercertificate.org/ for more information).
+
 -S[]::
 --gpg-sign[=]::
GPG-sign the resulting merge commit. The `keyid` argument is
diff --git a/builtin/merge.c b/builtin/merge.c
index 900bafdb45d0b..78c36e9bf353b 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -70,6 +70,7 @@ static int continue_current_merge;
 static int allow_unrelated_histories;
 static int show_progress = -1;
 static int default_to_upstream = 1;
+static int signoff;
 static const char *sign_commit;
 
 static struct strategy all_strategy[] = {
@@ -233,6 +234,7 @@ static struct option builtin_merge_options[] = {
{ OPTION_STRING, 'S', "gpg-sign", _commit, N_("key-id"),
  N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
OPT_BOOL(0, "overwrite-ignore", _ignore, N_("update ignored 
files (default)")),
+   OPT_BOOL(0, "signoff", , N_("add Signed-off-by:")),
OPT_END()
 };
 
@@ -763,6 +765,8 @@ static void prepare_to_commit(struct commit_list 
*remoteheads)
strbuf_addch(, '\n');
if (0 < option_edit)
strbuf_commented_addf(, _(merge_editor_comment), 
comment_line_char);
+   if (signoff)
+   append_signoff(, ignore_non_trailer(msg.buf, msg.len), 0);
write_file_buf(git_path_merge_msg(), msg.buf, msg.len);
if (run_commit_hook(0 < option_edit, get_index_file(), 
"prepare-commit-msg",
git_path_merge_msg(), "merge", NULL))
diff --git a/t/t7614-merge-signoff.sh b/t/t7614-merge-signoff.sh
new file mode 100755
index 0..c1b8446f491dc
--- /dev/null
+++ b/t/t7614-merge-signoff.sh
@@ -0,0 +1,69 @@
+#!/bin/sh
+
+test_description='git merge --signoff
+
+This test runs git merge --signoff and makes sure that it works.
+'
+
+. ./test-lib.sh
+
+# Setup test files
+test_setup() {
+   # Expected commit message after merge --signoff
+   cat >expected-signed <.*/>/")
+EOF
+
+   # Expected commit message after merge without --signoff (or with 
--no-signoff)
+   cat >expected-unsigned actual &&
+   test_cmp expected-unsigned actual
+'
+
+# Test for --no-signoff flag
+test_expect_success 'git merge --no-signoff flag cancels --signoff flag' '
+   git checkout master &&
+   test_commit master-branch-4 file4 4 &&
+   git checkout other-branch &&
+   git merge master --no-edit --signoff --no-signoff &&
+   git cat-file commit HEAD | sed -e "1,/^\$/d" >actual &&
+   test_cmp expected-unsigned actual
+'
+
+test_done

--
https://github.com/git/git/pull/383


[PATCH v2] add --signoff flag to `git-merge` command.

2017-07-04 Thread Łukasz Gryglicki
Some projects require every commit to be signed off.
Our workflow is to create feature branches and require every commit to
be signed off. When feature is finally approved we need to merge it into
master. Merge itself is usually trivial and is done by
`git merge origin/master`. Unfortunatelly this command have no --signoff
flag, so we need to either add signoff line manually or use
`git commit --amend -s` after the merge. First solution is not ideal
because not all developers are familiar with exact sign-off syntax.
The second solution works, but is obviously tedious.
This patch adds --signoff support to git-merge command. It works just
like --signoff in `git-commit` command.
More details here:
https://public-inbox.org/git/CAHv71zK5SqbwrBFX=a8-dy9h3kt4feymgv__p2gzznr0wua...@mail.gmail.com/T/#u

Signed-off-by: lukaszgryglicki 
---
 Documentation/git-merge.txt  |  8 +
 builtin/merge.c  |  4 +++
 t/t9904-git-merge-signoff.sh | 75 
 3 files changed, 87 insertions(+)
 create mode 100755 t/t9904-git-merge-signoff.sh

diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt
index 04fdd8cf086db..6b308ab6d0b52 100644
--- a/Documentation/git-merge.txt
+++ b/Documentation/git-merge.txt
@@ -64,6 +64,14 @@ OPTIONS
 ---
 include::merge-options.txt[]
 
+--signoff::
+   Add Signed-off-by line by the committer at the end of the commit
+   log message.  The meaning of a signoff depends on the project,
+   but it typically certifies that committer has
+   the rights to submit this work under the same license and
+   agrees to a Developer Certificate of Origin
+   (see http://developercertificate.org/ for more information).
+
 -S[]::
 --gpg-sign[=]::
GPG-sign the resulting merge commit. The `keyid` argument is
diff --git a/builtin/merge.c b/builtin/merge.c
index 900bafdb45d0b..78c36e9bf353b 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -70,6 +70,7 @@ static int continue_current_merge;
 static int allow_unrelated_histories;
 static int show_progress = -1;
 static int default_to_upstream = 1;
+static int signoff;
 static const char *sign_commit;
 
 static struct strategy all_strategy[] = {
@@ -233,6 +234,7 @@ static struct option builtin_merge_options[] = {
{ OPTION_STRING, 'S', "gpg-sign", _commit, N_("key-id"),
  N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
OPT_BOOL(0, "overwrite-ignore", _ignore, N_("update ignored 
files (default)")),
+   OPT_BOOL(0, "signoff", , N_("add Signed-off-by:")),
OPT_END()
 };
 
@@ -763,6 +765,8 @@ static void prepare_to_commit(struct commit_list 
*remoteheads)
strbuf_addch(, '\n');
if (0 < option_edit)
strbuf_commented_addf(, _(merge_editor_comment), 
comment_line_char);
+   if (signoff)
+   append_signoff(, ignore_non_trailer(msg.buf, msg.len), 0);
write_file_buf(git_path_merge_msg(), msg.buf, msg.len);
if (run_commit_hook(0 < option_edit, get_index_file(), 
"prepare-commit-msg",
git_path_merge_msg(), "merge", NULL))
diff --git a/t/t9904-git-merge-signoff.sh b/t/t9904-git-merge-signoff.sh
new file mode 100755
index 0..f542f136f5dda
--- /dev/null
+++ b/t/t9904-git-merge-signoff.sh
@@ -0,0 +1,75 @@
+#!/bin/sh
+
+test_description='git merge --signoff
+
+This test runs git merge --signoff and makes sure that it works.
+'
+
+. ./test-lib.sh
+
+# Setup test files
+test_setup() {
+   # A simples files to commit
+   echo "1" >file1
+   echo "2" >file2
+   echo "3" >file3
+   echo "4" >file4
+
+   # Expected commit message after merge --signoff
+   cat >expected-signed <.*/>/")
+EOF
+
+   # Expected commit message after merge without --signoff (or with 
--no-signoff)
+   cat >expected-unsigned actual &&
+   test_cmp expected-unsigned actual
+'
+
+# Test for --no-signoff flag
+test_expect_success 'git merge --no-signoff flag cancels --signoff flag' '
+   git checkout master &&
+   git add file4 &&
+   git commit -m master-branch-3 &&
+   git checkout other-branch &&
+   git merge master --no-edit --signoff --no-signoff &&
+   git cat-file commit HEAD | sed -e "1,/^\$/d" >actual &&
+   test_cmp expected-unsigned actual
+'
+
+test_done

--
https://github.com/git/git/pull/382


[PATCH] area: git-merge: add --signoff flag to git-merge

2017-07-03 Thread Łukasz Gryglicki
Added --signoff flag to `git-merge` command, added test coverage,
updated documentation.

Signed-off-by: lukaszgryglicki 
---
 Documentation/git-merge.txt  |  8 ++
 builtin/merge.c  |  4 +++
 t/t9904-git-merge-signoff.sh | 60 
 3 files changed, 72 insertions(+)
 create mode 100755 t/t9904-git-merge-signoff.sh

diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt
index 04fdd8cf086db..6b308ab6d0b52 100644
--- a/Documentation/git-merge.txt
+++ b/Documentation/git-merge.txt
@@ -64,6 +64,14 @@ OPTIONS
 ---
 include::merge-options.txt[]
 
+--signoff::
+   Add Signed-off-by line by the committer at the end of the commit
+   log message.  The meaning of a signoff depends on the project,
+   but it typically certifies that committer has
+   the rights to submit this work under the same license and
+   agrees to a Developer Certificate of Origin
+   (see http://developercertificate.org/ for more information).
+
 -S[]::
 --gpg-sign[=]::
GPG-sign the resulting merge commit. The `keyid` argument is
diff --git a/builtin/merge.c b/builtin/merge.c
index 900bafdb45d0b..cb09f4138136b 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -70,6 +70,7 @@ static int continue_current_merge;
 static int allow_unrelated_histories;
 static int show_progress = -1;
 static int default_to_upstream = 1;
+static int signoff;
 static const char *sign_commit;
 
 static struct strategy all_strategy[] = {
@@ -233,6 +234,7 @@ static struct option builtin_merge_options[] = {
{ OPTION_STRING, 'S', "gpg-sign", _commit, N_("key-id"),
  N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
OPT_BOOL(0, "overwrite-ignore", _ignore, N_("update ignored 
files (default)")),
+   OPT_BOOL(0, "signoff", , N_("add Signed-off-by:")),
OPT_END()
 };
 
@@ -775,6 +777,8 @@ static void prepare_to_commit(struct commit_list 
*remoteheads)
strbuf_stripspace(, 0 < option_edit);
if (!msg.len)
abort_commit(remoteheads, _("Empty commit message."));
+   if (signoff)
+   append_signoff(, ignore_non_trailer(msg.buf, msg.len), 0);
strbuf_release(_msg);
strbuf_addbuf(_msg, );
strbuf_release();
diff --git a/t/t9904-git-merge-signoff.sh b/t/t9904-git-merge-signoff.sh
new file mode 100755
index 0..eed15b9a85371
--- /dev/null
+++ b/t/t9904-git-merge-signoff.sh
@@ -0,0 +1,60 @@
+#!/bin/sh
+
+test_description='git merge --signoff
+
+This test runs git merge --signoff and make sure that it works.
+'
+
+. ./test-lib.sh
+
+# A simple files to commit
+cat >file1 /")
+EOF
+
+# Expected commit message after merge without --signoff (or with --no-signoff)
+cat >expected-unsigned < actual &&
+   test_cmp expected-signed actual
+'
+
+test_expect_success 'master --no-signoff does not add a sign-off line' '
+   git checkout master &&
+  git add file3 && git commit -m master-branch-2 &&
+  git checkout other-branch &&
+   git msob --no-signoff master &&
+   git cat-file commit HEAD | sed -e "1,/^\$/d" > actual &&
+   test_cmp expected-unsigned actual
+'
+
+test_done

--
https://github.com/git/git/pull/381