From patchwork Fri Apr 28 09:23:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Teng Long X-Patchwork-Id: 13226104 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 71FEAC77B60 for ; Fri, 28 Apr 2023 09:23:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231954AbjD1JXu (ORCPT ); Fri, 28 Apr 2023 05:23:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47316 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230017AbjD1JXt (ORCPT ); Fri, 28 Apr 2023 05:23:49 -0400 Received: from mail-pf1-x42f.google.com (mail-pf1-x42f.google.com [IPv6:2607:f8b0:4864:20::42f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7199930E8 for ; Fri, 28 Apr 2023 02:23:48 -0700 (PDT) Received: by mail-pf1-x42f.google.com with SMTP id d2e1a72fcca58-63b8b19901fso11503894b3a.3 for ; Fri, 28 Apr 2023 02:23:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1682673828; x=1685265828; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=NVYihN8aR3j/eJQhwBiADSvdvPg7dbbTDJpfSpUb5Uo=; b=CB2Haa+H+nNoZAFo2JRbBdPgFGeKrm/Jr5e2CToK/2V+uGEhtuIr8y+Jqut4puR7PJ CpFPNydmCgU6PS6tJ5Iys7SVJX9SYp3RPyrcbuEbfGg9uqmBeh2TdVro0ypBbfA0FyCb kdfD7SS3EoVX5GWL4SPhTBPOSVwYhtXBxIxr3SlQQBfB5AlxREyZk89FmvfWzpxwWNlo P0BX5CokSdjfRzcv468kSH4bgRmcF/al/OH16Jr1DgZ6czBOoU5pnSJOZ98ur4WPmtdJ hSGEDRYLc+ROa5525HTEqZ++htQ3jLleedux+I4yAj1/sRVEdj07aipI8cAk/ekaLSRN F73w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682673828; x=1685265828; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=NVYihN8aR3j/eJQhwBiADSvdvPg7dbbTDJpfSpUb5Uo=; b=MWmSz/NPVmTlnqQQlVtuZoR5Zet0wx8SPnJKAwu+BrmVCBl7TByM3zeabov5vM/wZu h+gxzDn7W+SrMuLLs2KOfQWat2rP+krmSpHjIEn4NAqA1X0RUuyYT90vfZHFMxvU/zdd Wy5KwUA5M31P17Taozk8L6Bmv5MlZfwZ4izcylb/fswCkKffYAHVa4mnBSwBUwjEHZQb pwqlE9EKw+FzXivcHSzUGIXzFlyQ47FudH8CoL2GTKjbdr2JL/sX/c+eVNwiUj6oSe2g bBB9UVMUzedV/ZfGIYZZHRz+In/NpbiDz7VAQEwl7/E9mQ8ttitWAeG1FUOcj4jvKBOc fZ9w== X-Gm-Message-State: AC+VfDw12Uk6QPXBmgbBqH5OTjNQSqzK1G7esYYo9LcPLou8XtiqB586 nYfaWAS8/LbQDUu8HRBWu94= X-Google-Smtp-Source: ACHHUZ4GkmgzuchFVw8D3wr5J4Ij0RsI8t0h3ALmsCsuSxDlbHmXHrxEClNIf5Ddw9C1dJ/WLbI9hQ== X-Received: by 2002:a05:6a00:1950:b0:628:1b3:d499 with SMTP id s16-20020a056a00195000b0062801b3d499mr7014130pfk.21.1682673827840; Fri, 28 Apr 2023 02:23:47 -0700 (PDT) Received: from localhost.localdomain ([47.246.101.51]) by smtp.gmail.com with ESMTPSA id i21-20020a056a00225500b0063b8f33cb81sm15107078pfu.93.2023.04.28.02.23.46 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 28 Apr 2023 02:23:47 -0700 (PDT) From: Teng Long X-Google-Original-From: Teng Long To: dyroneteng@gmail.com Cc: avarab@gmail.com, git@vger.kernel.org, gitster@pobox.com, sunshine@sunshineco.com, tenglong.tl@alibaba-inc.com Subject: [PATCH v9 1/6] notes.c: cleanup 'strbuf_grow' call in 'append_edit' Date: Fri, 28 Apr 2023 17:23:29 +0800 Message-ID: <0634434e2a3e40ef4af5013349202491d55fe1d7.1682671758.git.dyroneteng@gmail.com> X-Mailer: git-send-email 2.40.0.358.g2947072e.dirty In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Teng Long Let's cleanup the unnecessary 'strbuf_grow' call in 'append_edit'. This "strbuf_grow(&d.buf, size + 1);" is prepared for insert a blank line if needed, but actually when inserting, "strbuf_insertstr(&d.buf, 0, "\n");" will do the "grow" for us. 348f199b (builtin-notes: Refactor handling of -F option to allow combining -m and -F, 2010-02-13) added these to mimic the code introduced by 2347fae5 (builtin-notes: Add "append" subcommand for appending to note objects, 2010-02-13) that reads in previous note before the message. And the resulting code with explicit sizing is carried to this day. In the context of reading an existing note in, exact sizing may have made sense, but because the resulting note needs cleansing with stripspace() when appending with this option, such an exact sizing does not buy us all that much in practice. It may help avoiding overallocation due to ALLOC_GROW() slop, but nobody can feed so many long messages for it to matter from the command line. Signed-off-by: Teng Long Helped-by: Eric Sunshine Helped-by: Junio C Hamano --- builtin/notes.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/builtin/notes.c b/builtin/notes.c index 4ff44f1e..c501c6ee 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -219,7 +219,6 @@ static int parse_msg_arg(const struct option *opt, const char *arg, int unset) BUG_ON_OPT_NEG(unset); - strbuf_grow(&d->buf, strlen(arg) + 2); if (d->buf.len) strbuf_addch(&d->buf, '\n'); strbuf_addstr(&d->buf, arg); @@ -623,7 +622,6 @@ static int append_edit(int argc, const char **argv, const char *prefix) char *prev_buf = repo_read_object_file(the_repository, note, &type, &size); - strbuf_grow(&d.buf, size + 1); if (d.buf.len && prev_buf && size) strbuf_insertstr(&d.buf, 0, "\n"); if (prev_buf && size) From patchwork Fri Apr 28 09:23:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Teng Long X-Patchwork-Id: 13226106 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 377F0C77B60 for ; Fri, 28 Apr 2023 09:24:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345618AbjD1JYA (ORCPT ); Fri, 28 Apr 2023 05:24:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47324 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345391AbjD1JXv (ORCPT ); Fri, 28 Apr 2023 05:23:51 -0400 Received: from mail-pf1-x434.google.com (mail-pf1-x434.google.com [IPv6:2607:f8b0:4864:20::434]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6BEB62114 for ; Fri, 28 Apr 2023 02:23:50 -0700 (PDT) Received: by mail-pf1-x434.google.com with SMTP id d2e1a72fcca58-63b52ad6311so11020151b3a.2 for ; Fri, 28 Apr 2023 02:23:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1682673830; x=1685265830; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=xrANtvrLJ5OXmpR6s0jwv4UmUdJ899u5KZRlOyddvew=; b=lyANsD+1na3TkU5C226xSYif4JyWGD6OQx0ApMme17BD9Yf7maE8+YvouI65yBoF1O iomsM3eWbPv5XrlDpsrULoOsSJX+bDgKa4+wISCUXd+AT9H/kE29C47Z8EU0Et7DQfbN CgUUNSowFXhyD0sdSwjUYcsOAESPCeefPOQYw7zBuVVf5NmHy336Ej3kPJ1fZvH3ORis ++gcX1lIyIzy2F5yYzxC3FmXGR867B3FzWo1/6APsbi9qaemkt/OcjGfATc+1HTXgKYT IJq+Ag6r5Ch1D71w30FCOOUqQV2tyKkhs8gzdyFysnNuCxSgJwrynUm9aGrH8PjcfiRs A4pQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682673830; x=1685265830; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=xrANtvrLJ5OXmpR6s0jwv4UmUdJ899u5KZRlOyddvew=; b=Z1TtrHjA4yc3MkcP+nlVGzDym7hj/Ij1BsRKsGHx1M7W4UUKaSlaFpjZ4rwM3u7n04 aPLtySWzSZRnwnkZqr9nh2cl3OXTahhSihiDCPmi38I21dn71eY+QdmjIBesgJJ/sROh +QlMDp+0hyQo3YciSQUdOt6zQa9O0ORCktlWpEaFsAtLEPD7f+gKbKK9U6NrTopQLpKC 9tIulHtQrysD+i4LOpDtHrsV3fYlEQNr3YV38vsdfSruLVc3PQeqCfHCNEnFbtrcZr5I i4tdoYnebApxXvzWSXo+miyFa31uU6E/YZZLAueCSD4Hy0aOD1EY1VP9yCXsDWSCGW2T So0A== X-Gm-Message-State: AC+VfDxg+oRid6YzhI4D1fcxnz60OQIkn4fL5f0LxcxI8VLhlYJzZezQ IE+Nuuka0/tgW6RVRkbJGf/3+AOCmlqoCg== X-Google-Smtp-Source: ACHHUZ546/qjdGArWMW5rFxx0mlQQhZkv1OsBqVwuP3wQ7Il/B3piinptrQzacFsgyca8wI/hG5+bA== X-Received: by 2002:a05:6a00:24c1:b0:63d:2d99:2e91 with SMTP id d1-20020a056a0024c100b0063d2d992e91mr6782158pfv.28.1682673829908; Fri, 28 Apr 2023 02:23:49 -0700 (PDT) Received: from localhost.localdomain ([47.246.101.51]) by smtp.gmail.com with ESMTPSA id i21-20020a056a00225500b0063b8f33cb81sm15107078pfu.93.2023.04.28.02.23.48 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 28 Apr 2023 02:23:49 -0700 (PDT) From: Teng Long X-Google-Original-From: Teng Long To: dyroneteng@gmail.com Cc: avarab@gmail.com, git@vger.kernel.org, gitster@pobox.com, sunshine@sunshineco.com, tenglong.tl@alibaba-inc.com Subject: [PATCH v9 2/6] notes.c: use designated initializers for clarity Date: Fri, 28 Apr 2023 17:23:30 +0800 Message-ID: <4ad7840584191d6bbb3fcba72887aa569c797a15.1682671758.git.dyroneteng@gmail.com> X-Mailer: git-send-email 2.40.0.358.g2947072e.dirty In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Teng Long The "struct note_data d = { 0, 0, NULL, STRBUF_INIT };" style could be replaced with designated initializer for clarity. Signed-off-by: Teng Long Signed-off-by: Junio C Hamano --- builtin/notes.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builtin/notes.c b/builtin/notes.c index c501c6ee..9d8ca795 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -405,7 +405,7 @@ static int add(int argc, const char **argv, const char *prefix) struct notes_tree *t; struct object_id object, new_note; const struct object_id *note; - struct note_data d = { 0, 0, NULL, STRBUF_INIT }; + struct note_data d = { .buf = STRBUF_INIT }; struct option options[] = { OPT_CALLBACK_F('m', "message", &d, N_("message"), N_("note contents as a string"), PARSE_OPT_NONEG, @@ -571,7 +571,7 @@ static int append_edit(int argc, const char **argv, const char *prefix) const struct object_id *note; char *logmsg; const char * const *usage; - struct note_data d = { 0, 0, NULL, STRBUF_INIT }; + struct note_data d = { .buf = STRBUF_INIT }; struct option options[] = { OPT_CALLBACK_F('m', "message", &d, N_("message"), N_("note contents as a string"), PARSE_OPT_NONEG, From patchwork Fri Apr 28 09:23:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Teng Long X-Patchwork-Id: 13226107 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 88EC7C77B60 for ; Fri, 28 Apr 2023 09:24:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345652AbjD1JYC (ORCPT ); Fri, 28 Apr 2023 05:24:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47342 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229680AbjD1JXy (ORCPT ); Fri, 28 Apr 2023 05:23:54 -0400 Received: from mail-pf1-x42b.google.com (mail-pf1-x42b.google.com [IPv6:2607:f8b0:4864:20::42b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 874193C01 for ; Fri, 28 Apr 2023 02:23:52 -0700 (PDT) Received: by mail-pf1-x42b.google.com with SMTP id d2e1a72fcca58-63b5fca48bcso7717690b3a.0 for ; Fri, 28 Apr 2023 02:23:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1682673832; x=1685265832; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=1wd1K00lHiEYruSh/8mnS/IwOpa3xN+rbHeZE/i26A4=; b=W2/0p2NSlnpHtw5yv7pNq+nURkF1x8iJqoW6Mp33ptEFifoH+qi9KbR45Rox0u1F+A 67arBtNUMvnRQ2l8PamkLH+JWahxCAXdQ1hATW1/jESVStXUxtMh6J0AWtVte3+cEnqa pX/nXHcHpW7a7TbcGXuGApTTTd1KR5yOZw8KPwJq42gqcL1g3ZI+XRIA+mhw7hdBQZa5 4czBhs8SrMGep8wk0QyNFE1BcmEWW1F6rqgpzWKEe9Kx+nqiiWqfewsp2jO1SVLo7UAd Y4M8MTqR1fS8imDOqXH1toFzDkooF8ZKpm8/A/4FCb/kge9XsDPvfVB5Q2rgbFYc6opU TvVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682673832; x=1685265832; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=1wd1K00lHiEYruSh/8mnS/IwOpa3xN+rbHeZE/i26A4=; b=OwiEwNTmSWyRP3ZBk6db2Xup0H633q5hqmYiH5iwilF9pYvTwAnmiIIxwHPOOEniKz ost8g98wzTaG3irpsPYcFiKDBWhXeboXwRBifoMrOCiqBDwja+ulpuggn1AcHF/H05pn GQ4NBwdcnUxbJWK1XhN6cDw0dPH3IMytlwaF6AhuIA38xqhNbCDYjT7AkWPJ0N1UFbhO TiJxOoO58qZ2F/wqvgJZKjmTyWcDnX6QK8GA8S/OUwgzIvq3AZk3d9xxfPf4utDa3H7V BfpN9j1u/hR7tSHEX/6rfN3iMtN69RSULD6HsFWj51iDgv8C9Ji7HFm7jKelg9qJOi+h 6krQ== X-Gm-Message-State: AC+VfDwPOQYCeCeWNe+lPo8Eqcn4xl3E4lLOKCU3S3Yr5vlCtkMpbfHM kOuuATHeuTdvcHrf1QpYH2jb13mVHIZHwg== X-Google-Smtp-Source: ACHHUZ5/Dvuz16HcpmUSofNe35xZewJxuoo87Xe1LbTt9ARAYxMLjBfKh9U6j2JOnoS8D8mBnBITtA== X-Received: by 2002:aa7:88cf:0:b0:639:28de:a91e with SMTP id k15-20020aa788cf000000b0063928dea91emr7841354pff.17.1682673831884; Fri, 28 Apr 2023 02:23:51 -0700 (PDT) Received: from localhost.localdomain ([47.246.101.51]) by smtp.gmail.com with ESMTPSA id i21-20020a056a00225500b0063b8f33cb81sm15107078pfu.93.2023.04.28.02.23.50 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 28 Apr 2023 02:23:51 -0700 (PDT) From: Teng Long X-Google-Original-From: Teng Long To: dyroneteng@gmail.com Cc: avarab@gmail.com, git@vger.kernel.org, gitster@pobox.com, sunshine@sunshineco.com, tenglong.tl@alibaba-inc.com Subject: [PATCH v9 3/6] t3321: add test cases about the notes stripspace behavior Date: Fri, 28 Apr 2023 17:23:31 +0800 Message-ID: X-Mailer: git-send-email 2.40.0.358.g2947072e.dirty In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Teng Long Signed-off-by: Teng Long --- t/t3321-notes-stripspace.sh | 291 ++++++++++++++++++++++++++++++++++++ 1 file changed, 291 insertions(+) create mode 100755 t/t3321-notes-stripspace.sh diff --git a/t/t3321-notes-stripspace.sh b/t/t3321-notes-stripspace.sh new file mode 100755 index 00000000..89977873 --- /dev/null +++ b/t/t3321-notes-stripspace.sh @@ -0,0 +1,291 @@ +#!/bin/sh +# +# Copyright (c) 2023 Teng Long +# + +test_description='Test commit notes with stripspace behavior' + +. ./test-lib.sh + +MULTI_LF="$LF$LF$LF" +write_script fake_editor <<\EOF +echo "$MSG" >"$1" +echo "$MSG" >&2 +EOF +GIT_EDITOR=./fake_editor +export GIT_EDITOR + +test_expect_success 'setup the commit' ' + test_commit 1st +' + +test_expect_success 'add note by editor' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + first-line + + second-line + EOF + + MSG="${LF}first-line${MULTI_LF}second-line${LF}" git notes add && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'add note by specifying single "-m"' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + first-line + + second-line + EOF + + git notes add -m "${LF}first-line${MULTI_LF}second-line${LF}" && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'add note by specifying multiple "-m"' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + first-line + + second-line + EOF + + git notes add -m "${LF}" \ + -m "first-line" \ + -m "${MULTI_LF}" \ + -m "second-line" \ + -m "${LF}" && + git notes show >actual && + test_cmp expect actual +' + + +test_expect_success 'append note by editor' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + first-line + + second-line + EOF + + git notes add -m "first-line" && + MSG="${MULTI_LF}second-line${LF}" git notes append && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'append note by specifying single "-m"' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + first-line + + second-line + EOF + + git notes add -m "${LF}first-line" && + git notes append -m "${MULTI_LF}second-line${LF}" && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'append note by specifying multiple "-m"' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + first-line + + second-line + EOF + + git notes add -m "${LF}first-line" && + git notes append -m "${MULTI_LF}" \ + -m "second-line" \ + -m "${LF}" && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'add note by specifying single "-F"' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + first-line + + second-line + EOF + + cat >note-file <<-EOF && + ${LF} + first-line + ${MULTI_LF} + second-line + ${LF} + EOF + + git notes add -F note-file && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'add notes by specifying multiple "-F"' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + file-1-first-line + + file-1-second-line + + file-2-first-line + + file-2-second-line + EOF + + cat >note-file-1 <<-EOF && + ${LF} + file-1-first-line + ${MULTI_LF} + file-1-second-line + ${LF} + EOF + + cat >note-file-2 <<-EOF && + ${LF} + file-2-first-line + ${MULTI_LF} + file-2-second-line + ${LF} + EOF + + git notes add -F note-file-1 -F note-file-2 && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'append note by specifying single "-F"' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + initial-line + + first-line + + second-line + EOF + + cat >note-file <<-EOF && + ${LF} + first-line + ${MULTI_LF} + second-line + ${LF} + EOF + + git notes add -m "initial-line" && + git notes append -F note-file && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'append notes by specifying multiple "-F"' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + initial-line + + file-1-first-line + + file-1-second-line + + file-2-first-line + + file-2-second-line + EOF + + cat >note-file-1 <<-EOF && + ${LF} + file-1-first-line + ${MULTI_LF} + file-1-second-line + ${LF} + EOF + + cat >note-file-2 <<-EOF && + ${LF} + file-2-first-line + ${MULTI_LF} + file-2-second-line + ${LF} + EOF + + git notes add -m "initial-line" && + git notes append -F note-file-1 -F note-file-2 && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'add notes with empty messages' ' + rev=$(git rev-parse HEAD) && + git notes add -m "${LF}" \ + -m "${MULTI_LF}" \ + -m "${LF}" >actual 2>&1 && + test_i18ngrep "Removing note for object" actual +' + +test_expect_success 'add note by specifying "-C" , do not stripspace is the default behavior' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + ${LF} + first-line + ${MULTI_LF} + second-line + ${LF} + EOF + + cat expect | git hash-object -w --stdin >blob && + git notes add -C $(cat blob) && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'add notes with "-C" and "-m", "-m" will stripspace all together' ' + test_when_finished "git notes remove" && + cat >data <<-EOF && + ${LF} + first-line + ${MULTI_LF} + second-line + ${LF} + EOF + + cat >expect <<-EOF && + first-line + + second-line + + third-line + EOF + + cat data | git hash-object -w --stdin >blob && + git notes add -C $(cat blob) -m "third-line" && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'add notes with "-m" and "-C", "-C" will not stripspace all together' ' + test_when_finished "git notes remove" && + cat >data <<-EOF && + + second-line + EOF + + cat >expect <<-EOF && + first-line + ${LF} + second-line + EOF + + cat data | git hash-object -w --stdin >blob && + git notes add -m "first-line" -C $(cat blob) && + git notes show >actual && + test_cmp expect actual +' + +test_done From patchwork Fri Apr 28 09:23:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Teng Long X-Patchwork-Id: 13226108 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C39A7C77B7C for ; Fri, 28 Apr 2023 09:24:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345451AbjD1JYD (ORCPT ); Fri, 28 Apr 2023 05:24:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47478 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345539AbjD1JX7 (ORCPT ); Fri, 28 Apr 2023 05:23:59 -0400 Received: from mail-pf1-x42a.google.com (mail-pf1-x42a.google.com [IPv6:2607:f8b0:4864:20::42a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B3187468C for ; Fri, 28 Apr 2023 02:23:54 -0700 (PDT) Received: by mail-pf1-x42a.google.com with SMTP id d2e1a72fcca58-63b57c49c4cso7700589b3a.3 for ; Fri, 28 Apr 2023 02:23:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1682673834; x=1685265834; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=UosYcQykifpwor09cUERJH7EP11mJMbjtx4mo8ApxKo=; b=Sr3iBMVMnP74hpUDBGiajHliEXRP3VW0cxBIeU0x6/dq6d938iZRr7tCyimvTx0X/e x+lc/IFtdeBIv333EGeK/dXolHGTa4dAWhKHu3vVWy24BRBB1SFLjYcCWWSrJTvso+bS H63kJmAY9gxvckhN9pIL5fUfCGsjw+Il7SQT6C4fOnx3DuBoJ/Ii3qZwlPqCj3e29zYa ZB2oPM8dWnbwGuk2MBs7uBfBF6CuTxJy1Yv5et2vX3qd0tWaZyB0c+0dOzhgAe+U8nQa lbFwLirby7MrERbxQNweZmmj3DXWoD3e7fy1ydEbyAgtgU/QVPhi3ItMWsiLZ8c6URuG QrpA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682673834; x=1685265834; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=UosYcQykifpwor09cUERJH7EP11mJMbjtx4mo8ApxKo=; b=g8iS1II6D72YRMljc6oPL2Gxm7T9ry51c0b/3tICR6bFY1nfzusY6FVcNoEeN6x9LL k/zpRaE51kMX+iRmCQefi6aVMR6u8rxNmSfLWm16hK0VoBEbEQ2bPY7RVfyu8eA+MH11 RK7CDFd2eVmWuICej5VT50V6dKp7987ookSFvQlwscaYa+I1IMME3jHJQmVbOawkj5Ug ZHm2RPn3vAcWlBM0GQAFyPxpd//tUY5mk4VFESQ7RuYvZmeuUE13LEYEVl9bff95NE4p jt0yx6+QwYIdIxUISASKyBAR0rCNA376D91SXOW7pmjR/RKUNB2k6Hr/V52iLHW65n9i yy+A== X-Gm-Message-State: AC+VfDwcytyGkFXmRyvsEgc8Wp6DU2YUR8u509KpcZKPKqwphga5CT03 gePO8R4944ISey2IO9kLuTW3uA+lzhYr7w== X-Google-Smtp-Source: ACHHUZ6XFT/ZxBL+fiw/kgyJnVOfHRI6RtLy9nBxCu92P+lQOxGM599AGpZZDmC9BnHILuZc35R7dw== X-Received: by 2002:a05:6a00:1385:b0:63d:4752:4da3 with SMTP id t5-20020a056a00138500b0063d47524da3mr8031682pfg.25.1682673834001; Fri, 28 Apr 2023 02:23:54 -0700 (PDT) Received: from localhost.localdomain ([47.246.101.51]) by smtp.gmail.com with ESMTPSA id i21-20020a056a00225500b0063b8f33cb81sm15107078pfu.93.2023.04.28.02.23.52 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 28 Apr 2023 02:23:53 -0700 (PDT) From: Teng Long X-Google-Original-From: Teng Long To: dyroneteng@gmail.com Cc: avarab@gmail.com, git@vger.kernel.org, gitster@pobox.com, sunshine@sunshineco.com, tenglong.tl@alibaba-inc.com Subject: [PATCH v9 4/6] notes.c: introduce '--separator=' option Date: Fri, 28 Apr 2023 17:23:32 +0800 Message-ID: X-Mailer: git-send-email 2.40.0.358.g2947072e.dirty In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Teng Long When adding new notes or appending to an existing notes, we will insert a blank line between the paragraphs, like: $ git notes add -m foo -m bar $ git notes show HEAD foo bar The default behavour sometimes is not enough, the user may want to use a custom delimiter between paragraphs, like when specifying '-m', '-F', '-C', '-c' options. So this commit introduce a new '--separator' option for 'git notes add' and 'git notes append', for example when executing: $ git notes add -m foo -m bar --separator="-" $ git notes show HEAD foo - bar a newline is added to the value given to --separator if it does not end with one already. So when executing: $ git notes add -m foo -m bar --separator="-" and $ export LF=" " $ git notes add -m foo -m bar --separator="-$LF" Both the two exections produce the same result. The reason we use a "strbuf" array to concat but not "string_list", is that the binary file content may contain '\0' in the middle, this will cause the corrupt result if using a string to save. Signed-off-by: Teng Long --- Documentation/git-notes.txt | 21 ++++-- builtin/notes.c | 108 ++++++++++++++++++++++++------- t/t3301-notes.sh | 126 ++++++++++++++++++++++++++++++++++++ 3 files changed, 226 insertions(+), 29 deletions(-) diff --git a/Documentation/git-notes.txt b/Documentation/git-notes.txt index efbc10f0..59980b21 100644 --- a/Documentation/git-notes.txt +++ b/Documentation/git-notes.txt @@ -9,9 +9,9 @@ SYNOPSIS -------- [verse] 'git notes' [list []] -'git notes' add [-f] [--allow-empty] [-F | -m | (-c | -C) ] [] +'git notes' add [-f] [--allow-empty] [--separator=] [-F | -m | (-c | -C) ] [] 'git notes' copy [-f] ( --stdin | [] ) -'git notes' append [--allow-empty] [-F | -m | (-c | -C) ] [] +'git notes' append [--allow-empty] [--separator=] [-F | -m | (-c | -C) ] [] 'git notes' edit [--allow-empty] [] 'git notes' show [] 'git notes' merge [-v | -q] [-s ] @@ -65,7 +65,9 @@ add:: However, if you're using `add` interactively (using an editor to supply the notes contents), then - instead of aborting - the existing notes will be opened in the editor (like the `edit` - subcommand). + subcommand). If you specify multiple `-m` and `-F`, a blank + line will be inserted between the messages. Use the `--separator` + option to insert other delimiters. copy:: Copy the notes for the first object onto the second object (defaults to @@ -85,8 +87,12 @@ corresponding . (The optional `` is ignored so that the command can read the input given to the `post-rewrite` hook.) append:: - Append to the notes of an existing object (defaults to HEAD). - Creates a new notes object if needed. + Append new message(s) given by `-m` or `-F` options to an + existing note, or add them as a new note if one does not + exist, for the object (defaults to HEAD). When appending to + an existing note, a blank line is added before each new + message as an inter-paragraph separator. The separator can + be customized with the `--separator` option. edit:: Edit the notes for a given object (defaults to HEAD). @@ -159,6 +165,11 @@ OPTIONS Allow an empty note object to be stored. The default behavior is to automatically remove empty notes. +--separator :: + Specify a string used as a custom inter-paragraph separator + (a newline is added at the end as needed). Defaults to a + blank line. + --ref :: Manipulate the notes tree in . This overrides `GIT_NOTES_REF` and the "core.notesRef" configuration. The ref diff --git a/builtin/notes.c b/builtin/notes.c index 9d8ca795..3215bce1 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -8,6 +8,7 @@ */ #include "cache.h" +#include "alloc.h" #include "config.h" #include "builtin.h" #include "gettext.h" @@ -27,11 +28,12 @@ #include "worktree.h" #include "write-or-die.h" +static char *separator = "\n"; static const char * const git_notes_usage[] = { N_("git notes [--ref ] [list []]"), - N_("git notes [--ref ] add [-f] [--allow-empty] [-m | -F | (-c | -C) ] []"), + N_("git notes [--ref ] add [-f] [--allow-empty] [--separator=] [-m | -F | (-c | -C) ] []"), N_("git notes [--ref ] copy [-f] "), - N_("git notes [--ref ] append [--allow-empty] [-m | -F | (-c | -C) ] []"), + N_("git notes [--ref ] append [--allow-empty] [--separator=] [-m | -F | (-c | -C) ] []"), N_("git notes [--ref ] edit [--allow-empty] []"), N_("git notes [--ref ] show []"), N_("git notes [--ref ] merge [-v | -q] [-s ] "), @@ -99,11 +101,19 @@ static const char * const git_notes_get_ref_usage[] = { static const char note_template[] = N_("Write/edit the notes for the following object:"); +struct note_msg { + int stripspace; + struct strbuf buf; +}; + struct note_data { int given; int use_editor; char *edit_path; struct strbuf buf; + struct note_msg **messages; + size_t msg_nr; + size_t msg_alloc; }; static void free_note_data(struct note_data *d) @@ -113,6 +123,12 @@ static void free_note_data(struct note_data *d) free(d->edit_path); } strbuf_release(&d->buf); + + while (d->msg_nr--) { + strbuf_release(&d->messages[d->msg_nr]->buf); + free(d->messages[d->msg_nr]); + } + free(d->messages); } static int list_each_note(const struct object_id *object_oid, @@ -213,65 +229,96 @@ static void write_note_data(struct note_data *d, struct object_id *oid) } } +static void insert_separator(struct strbuf *message, size_t pos) +{ + if (separator[strlen(separator) - 1] == '\n') + strbuf_addstr(message, separator); + else + strbuf_insertf(message, pos, "%s%s", separator, "\n"); +} + +static void concat_messages(struct note_data *d) +{ + struct strbuf msg = STRBUF_INIT; + + size_t i; + for (i = 0; i < d->msg_nr ; i++) { + if (d->buf.len) + insert_separator(&d->buf, d->buf.len); + strbuf_add(&msg, d->messages[i]->buf.buf, d->messages[i]->buf.len); + strbuf_addbuf(&d->buf, &msg); + if (d->messages[i]->stripspace) + strbuf_stripspace(&d->buf, 0); + strbuf_reset(&msg); + } + strbuf_release(&msg); +} + static int parse_msg_arg(const struct option *opt, const char *arg, int unset) { struct note_data *d = opt->value; + struct note_msg *msg = xmalloc(sizeof(*msg)); BUG_ON_OPT_NEG(unset); - if (d->buf.len) - strbuf_addch(&d->buf, '\n'); - strbuf_addstr(&d->buf, arg); - strbuf_stripspace(&d->buf, 0); - - d->given = 1; + strbuf_init(&msg->buf, strlen(arg)); + strbuf_addstr(&msg->buf, arg); + ALLOC_GROW_BY(d->messages, d->msg_nr, 1, d->msg_alloc); + d->messages[d->msg_nr - 1] = msg; + msg->stripspace = 1; return 0; } static int parse_file_arg(const struct option *opt, const char *arg, int unset) { struct note_data *d = opt->value; + struct note_msg *msg = xmalloc(sizeof(*msg)); BUG_ON_OPT_NEG(unset); - if (d->buf.len) - strbuf_addch(&d->buf, '\n'); + strbuf_init(&msg->buf , 0); if (!strcmp(arg, "-")) { - if (strbuf_read(&d->buf, 0, 1024) < 0) + if (strbuf_read(&msg->buf, 0, 1024) < 0) die_errno(_("cannot read '%s'"), arg); - } else if (strbuf_read_file(&d->buf, arg, 1024) < 0) + } else if (strbuf_read_file(&msg->buf, arg, 1024) < 0) die_errno(_("could not open or read '%s'"), arg); - strbuf_stripspace(&d->buf, 0); - d->given = 1; + ALLOC_GROW_BY(d->messages, d->msg_nr, 1, d->msg_alloc); + d->messages[d->msg_nr - 1] = msg; + msg->stripspace = 1; return 0; } static int parse_reuse_arg(const struct option *opt, const char *arg, int unset) { struct note_data *d = opt->value; - char *buf; + struct note_msg *msg = xmalloc(sizeof(*msg)); + char *value; struct object_id object; enum object_type type; unsigned long len; BUG_ON_OPT_NEG(unset); - if (d->buf.len) - strbuf_addch(&d->buf, '\n'); - + strbuf_init(&msg->buf, 0); if (repo_get_oid(the_repository, arg, &object)) die(_("failed to resolve '%s' as a valid ref."), arg); - if (!(buf = repo_read_object_file(the_repository, &object, &type, &len))) + if (!(value = repo_read_object_file(the_repository, &object, &type, &len))) die(_("failed to read object '%s'."), arg); if (type != OBJ_BLOB) { - free(buf); + strbuf_release(&msg->buf); + free(value); + free(msg); die(_("cannot read note data from non-blob object '%s'."), arg); } - strbuf_add(&d->buf, buf, len); - free(buf); - d->given = 1; + strbuf_add(&msg->buf, value, len); + free(value); + + msg->buf.len = len; + ALLOC_GROW_BY(d->messages, d->msg_nr, 1, d->msg_alloc); + d->messages[d->msg_nr - 1] = msg; + msg->stripspace = 0; return 0; } @@ -406,6 +453,7 @@ static int add(int argc, const char **argv, const char *prefix) struct object_id object, new_note; const struct object_id *note; struct note_data d = { .buf = STRBUF_INIT }; + struct option options[] = { OPT_CALLBACK_F('m', "message", &d, N_("message"), N_("note contents as a string"), PARSE_OPT_NONEG, @@ -422,6 +470,8 @@ static int add(int argc, const char **argv, const char *prefix) OPT_BOOL(0, "allow-empty", &allow_empty, N_("allow storing empty note")), OPT__FORCE(&force, N_("replace existing notes"), PARSE_OPT_NOCOMPLETE), + OPT_STRING(0, "separator", &separator, N_("separator"), + N_("insert between paragraphs")), OPT_END() }; @@ -433,6 +483,10 @@ static int add(int argc, const char **argv, const char *prefix) usage_with_options(git_notes_add_usage, options); } + if (d.msg_nr) + concat_messages(&d); + d.given = !!d.buf.len; + object_ref = argc > 1 ? argv[1] : "HEAD"; if (repo_get_oid(the_repository, object_ref, &object)) @@ -587,6 +641,8 @@ static int append_edit(int argc, const char **argv, const char *prefix) parse_reuse_arg), OPT_BOOL(0, "allow-empty", &allow_empty, N_("allow storing empty note")), + OPT_STRING(0, "separator", &separator, N_("separator"), + N_("insert between paragraphs")), OPT_END() }; int edit = !strcmp(argv[0], "edit"); @@ -600,6 +656,10 @@ static int append_edit(int argc, const char **argv, const char *prefix) usage_with_options(usage, options); } + if (d.msg_nr) + concat_messages(&d); + d.given = !!d.buf.len; + if (d.given && edit) fprintf(stderr, _("The -m/-F/-c/-C options have been deprecated " "for the 'edit' subcommand.\n" @@ -623,7 +683,7 @@ static int append_edit(int argc, const char **argv, const char *prefix) &type, &size); if (d.buf.len && prev_buf && size) - strbuf_insertstr(&d.buf, 0, "\n"); + insert_separator(&d.buf, 0); if (prev_buf && size) strbuf_insert(&d.buf, 0, prev_buf, size); free(prev_buf); diff --git a/t/t3301-notes.sh b/t/t3301-notes.sh index 3288aaec..dbadcf13 100755 --- a/t/t3301-notes.sh +++ b/t/t3301-notes.sh @@ -362,6 +362,7 @@ test_expect_success 'do not create empty note with -m ""' ' ' test_expect_success 'create note with combination of -m and -F' ' + test_when_finished git notes remove HEAD && cat >expect-combine_m_and_F <<-EOF && foo @@ -380,6 +381,25 @@ test_expect_success 'create note with combination of -m and -F' ' test_cmp expect-combine_m_and_F actual ' +test_expect_success 'create note with combination of -m and -F and --separator' ' + cat >expect-combine_m_and_F <<-\EOF && + foo + ------- + xyzzy + ------- + bar + ------- + zyxxy + ------- + baz + EOF + echo "xyzzy" >note_a && + echo "zyxxy" >note_b && + git notes add -m "foo" -F note_a -m "bar" -F note_b -m "baz" --separator "-------" && + git notes show >actual && + test_cmp expect-combine_m_and_F actual +' + test_expect_success 'remove note with "git notes remove"' ' git notes remove HEAD^ && git notes remove && @@ -521,6 +541,85 @@ test_expect_success 'listing non-existing notes fails' ' test_must_be_empty actual ' +test_expect_success 'append: specify an empty separator' ' + test_when_finished git notes remove HEAD && + cat >expect <<-\EOF && + notes-1 + + notes-2 + EOF + + git notes add -m "notes-1" && + git notes append --separator="" -m "notes-2" && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'append: specify separator with line break' ' + test_when_finished git notes remove HEAD && + cat >expect <<-\EOF && + notes-1 + ------- + notes-2 + EOF + + git notes add -m "notes-1" && + git notes append --separator="-------$LF" -m "notes-2" && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'append: specify separator without line break' ' + test_when_finished git notes remove HEAD && + cat >expect <<-\EOF && + notes-1 + ------- + notes-2 + EOF + + git notes add -m "notes-1" && + git notes append --separator="-------" -m "notes-2" && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'append: specify separator with multiple messages' ' + test_when_finished git notes remove HEAD && + cat >expect <<-\EOF && + notes-1 + ------- + notes-2 + ------- + notes-3 + EOF + + git notes add -m "notes-1" && + git notes append --separator="-------" -m "notes-2" -m "notes-3" && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'append note with combination of -m and -F and --separator' ' + test_when_finished git notes remove HEAD && + cat >expect-combine_m_and_F <<-\EOF && + m-notes-1 + ------- + f-notes-1 + ------- + m-notes-2 + ------- + f-notes-2 + ------- + m-notes-3 + EOF + + echo "f-notes-1" >note_a && + echo "f-notes-2" >note_b && + git notes append -m "m-notes-1" -F note_a -m "m-notes-2" -F note_b -m "m-notes-3" --separator "-------" && + git notes show >actual && + test_cmp expect-combine_m_and_F actual +' + test_expect_success 'append to existing note with "git notes append"' ' cat >expect <<-EOF && Initial set of notes @@ -818,6 +917,33 @@ test_expect_success 'create note from blob with "git notes add -C" reuses blob i test_cmp blob actual ' +test_expect_success 'create note from blob with "-C", also specify "-m", "-F" and "--separator"' ' + # 8th will be reuseed in following tests, so rollback when the test is done + test_when_finished "git notes remove && git notes add -C $(cat blob)" && + commit=$(git rev-parse HEAD) && + cat >expect <<-EOF && + commit $commit + Author: A U Thor + Date: Thu Apr 7 15:20:13 2005 -0700 + + ${indent}8th + + Notes: + ${indent}This is a blob object + ${indent}------- + ${indent}This is created by -m + ${indent}------- + ${indent}This is created by -F + EOF + + git notes remove && + echo "This is a blob object" | git hash-object -w --stdin >blob && + echo "This is created by -F" >note_a && + git notes add -C $(cat blob) -m "This is created by -m" -F note_a --separator="-------" && + git log -1 >actual && + test_cmp expect actual +' + test_expect_success 'create note from other note with "git notes add -c"' ' test_commit 9th && commit=$(git rev-parse HEAD) && From patchwork Fri Apr 28 09:23:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Teng Long X-Patchwork-Id: 13226109 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6FCCFC77B61 for ; Fri, 28 Apr 2023 09:24:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345526AbjD1JYF (ORCPT ); Fri, 28 Apr 2023 05:24:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47494 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345423AbjD1JX7 (ORCPT ); Fri, 28 Apr 2023 05:23:59 -0400 Received: from mail-pf1-x42b.google.com (mail-pf1-x42b.google.com [IPv6:2607:f8b0:4864:20::42b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E6E7F49E1 for ; Fri, 28 Apr 2023 02:23:56 -0700 (PDT) Received: by mail-pf1-x42b.google.com with SMTP id d2e1a72fcca58-63b5c4c76aaso6756453b3a.2 for ; Fri, 28 Apr 2023 02:23:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1682673836; x=1685265836; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ML6J1lQAN7PCv6OAMZrFzhp4NSsYmaYu4Jgfios8sB8=; b=Q+Povm+HVH2U7W4d+dZkL6Pe4kI4ll9gYlsv9F/nu/L097td7WkWgtwHgKX1iL3W+7 7yHrpWa0/9TyC0Vi6uTB4vLNhNFtZrip8+xb4/bh5isqmhPnGA9syK4cKCbPZ130pVJh oQ5aKmHGH+T4b50JZlhdl3D+WPK047cb82iAQ22CUmZjsHk0fR9oyIRktBBqj4nKey9h xZs7g4UDOLQPS0kBFDuYmQKW/b15pYk4z/GgiRpzNKJLY/CujhVK1rrWaSEnn2LdrkXH 5OSayI9PAQQdi2ynR6p8R74hA9A5K/uVPdMfx2KrbZzMJxEQEPk6E8lgf8ALj/hQ/Tiu qWwQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682673836; x=1685265836; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ML6J1lQAN7PCv6OAMZrFzhp4NSsYmaYu4Jgfios8sB8=; b=KwUzEoUJXOtoB8xxBlXZTuLVLUiBWzCWR6QH348VPJYjbJYOJPmciLsHX2KQHesbS2 ZUDOzn1jPEkqVM7l7t2cVCSYmXNOQ/rbeW5ahDtSwHvnRLdWLgCvpBj43mIj3oG0qBb5 Y115T2wBsXWiAS6p4ztNW7c13QzH1ZuT7ifAJT1ufzvbmcg+/xzv0Bin1kMZoS8DR2GI OTs/EAe4vDN9McyBidGI9rAGorzQ5m7NzjUpGmofzcKuHxZDWdoAO/P2PkBZZxWrxT0L 0wY49PCN7YwxFcdf05wjisCC23sOqcYVoteCFVZ46QaMSvDb9BNSPs374xma9n1HyXYa YfRg== X-Gm-Message-State: AC+VfDyjGCQiGZPRYe4hm5/JykcmiFHyDWp4Q7TGhZA4SdbnHxoKpwuP MYjq5P65+YYC3wyPdxe6uas= X-Google-Smtp-Source: ACHHUZ4x4Ri1jUQ4olPVbnxfE3nUKFSkri5BMntP9hZvLLnHqn4i8j6k5GUJ1Kfv88ojxzFhheA31g== X-Received: by 2002:a05:6a00:a0e:b0:63d:47ab:65ed with SMTP id p14-20020a056a000a0e00b0063d47ab65edmr7177681pfh.7.1682673835968; Fri, 28 Apr 2023 02:23:55 -0700 (PDT) Received: from localhost.localdomain ([47.246.101.51]) by smtp.gmail.com with ESMTPSA id i21-20020a056a00225500b0063b8f33cb81sm15107078pfu.93.2023.04.28.02.23.54 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 28 Apr 2023 02:23:55 -0700 (PDT) From: Teng Long X-Google-Original-From: Teng Long To: dyroneteng@gmail.com Cc: avarab@gmail.com, git@vger.kernel.org, gitster@pobox.com, sunshine@sunshineco.com, tenglong.tl@alibaba-inc.com Subject: [PATCH v9 5/6] notes.c: append separator instead of insert by pos Date: Fri, 28 Apr 2023 17:23:33 +0800 Message-ID: X-Mailer: git-send-email 2.40.0.358.g2947072e.dirty In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Teng Long Rename "insert_separator" to "append_separator" and also remove the "postion" argument, this serves two purpose: The first is that when specifying more than one "-m" ( like "-F", etc) to "git notes add" or "git notes append", the order of them matters, which means we need to append the each separator and message in turn, so we don't have to make the caller specify the position, the "append" operation is enough and clear. The second is that when we execute the "git notes append" subcommand, we need to combine the "prev_note" and "current_note" to get the final result. Before, we inserted a newline character at the beginning of "current_note". Now, we will append a newline to the end of "prev_note" instead, this will give the consisitent results. Signed-off-by: Teng Long --- builtin/notes.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/builtin/notes.c b/builtin/notes.c index 3215bce1..e32f2453 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -229,12 +229,12 @@ static void write_note_data(struct note_data *d, struct object_id *oid) } } -static void insert_separator(struct strbuf *message, size_t pos) +static void append_separator(struct strbuf *message) { if (separator[strlen(separator) - 1] == '\n') strbuf_addstr(message, separator); else - strbuf_insertf(message, pos, "%s%s", separator, "\n"); + strbuf_addf(message, "%s%s", separator, "\n"); } static void concat_messages(struct note_data *d) @@ -244,7 +244,7 @@ static void concat_messages(struct note_data *d) size_t i; for (i = 0; i < d->msg_nr ; i++) { if (d->buf.len) - insert_separator(&d->buf, d->buf.len); + append_separator(&d->buf); strbuf_add(&msg, d->messages[i]->buf.buf, d->messages[i]->buf.len); strbuf_addbuf(&d->buf, &msg); if (d->messages[i]->stripspace) @@ -679,14 +679,17 @@ static int append_edit(int argc, const char **argv, const char *prefix) /* Append buf to previous note contents */ unsigned long size; enum object_type type; - char *prev_buf = repo_read_object_file(the_repository, note, - &type, &size); + struct strbuf buf = STRBUF_INIT; + char *prev_buf = repo_read_object_file(the_repository, note, &type, &size); - if (d.buf.len && prev_buf && size) - insert_separator(&d.buf, 0); if (prev_buf && size) - strbuf_insert(&d.buf, 0, prev_buf, size); + strbuf_add(&buf, prev_buf, size); + if (d.buf.len && prev_buf && size) + append_separator(&buf); + strbuf_insert(&d.buf, 0, buf.buf, buf.len); + free(prev_buf); + strbuf_release(&buf); } if (d.buf.len || allow_empty) { From patchwork Fri Apr 28 09:23:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Teng Long X-Patchwork-Id: 13226116 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 94802C77B60 for ; Fri, 28 Apr 2023 09:24:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345670AbjD1JYJ (ORCPT ); Fri, 28 Apr 2023 05:24:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47494 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345500AbjD1JYB (ORCPT ); Fri, 28 Apr 2023 05:24:01 -0400 Received: from mail-pf1-x42b.google.com (mail-pf1-x42b.google.com [IPv6:2607:f8b0:4864:20::42b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A17B646BE for ; Fri, 28 Apr 2023 02:23:58 -0700 (PDT) Received: by mail-pf1-x42b.google.com with SMTP id d2e1a72fcca58-63b78b344d5so7467808b3a.1 for ; Fri, 28 Apr 2023 02:23:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1682673838; x=1685265838; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=9hy86/ME7LhiWo6cydx+EBcbsGouhw96DiQL8NIb6Ec=; b=kHzZxmewvDi5/ghNgFrmTdDU/NtpSjY9fiOU5zzUz2ObAQhowDoZnZUQNgD+v0v2XV VWetGVN/ApUh0bYCWRCmvJNPORm+4RobdjAuDxzgnYOFasTE7u8KPUqZyIj52EZjEikE mH0PlHqpxsU/j5g4UeXM2EXDRF8tto4vVGw911/Loi9o9yRyCZyL4Uhz/72nAf9qRW90 0NrGInKIo7hVydBJGpC0u3C3KbOFcT8rfH9rJsP9wfXKQ2kAAtc7zxmoy/PNzbMf5qR3 3aV1roqwCYWgWJtHxxi0BjDF+N+P4Zk7w4CitMYP4/RUyl92gbLW7IYsLqieIpKhtki9 9i/Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682673838; x=1685265838; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=9hy86/ME7LhiWo6cydx+EBcbsGouhw96DiQL8NIb6Ec=; b=jc0TFMZJXpznU8i6QYnQeEI4tvprcspDRAYHSJPRaMK0m8KtqF0ukW0ixvW+kqgiUv cEuJYvTdXxq113J8I1yJHL8nS2f9Nk9ti2L0SZb4WJugpt62fVCtKnTbdhr9z87EusUc 6KMkPW5glzknCneaz0Uh3VrqSGX+8QnfL2DEpt/0p954Dtryrz2FhFt0TVH+9NDdz2Os 1GADf5NXwKW9myUUuJXc2VnCH3eqZ0ZvvAcruv4ikXRfhUBI/8kFN8M6VZRYodY+0SIO HE+zxhYIddI2UtmWDF7PQIKJQjb0xJJWJmwqjrnFrWwwP64KnmOtl5hXVK3fhjxMMT8B chEw== X-Gm-Message-State: AC+VfDymhHTdG2JJKRAvl22GnuNepogSK020Vst0COfotmWVkMqc/edy 9/cZDv4C5DFRqihPjzSwTE8GeRsfm6Nolg== X-Google-Smtp-Source: ACHHUZ7aursqcjJMbSHY8xS3j+qqjHrMRHd1WkrO+IsB1yCYS1+gHTVi5k0zOsmeiQoJs10QBzgbDg== X-Received: by 2002:a05:6a00:1515:b0:640:e12a:3a20 with SMTP id q21-20020a056a00151500b00640e12a3a20mr7543924pfu.1.1682673837967; Fri, 28 Apr 2023 02:23:57 -0700 (PDT) Received: from localhost.localdomain ([47.246.101.51]) by smtp.gmail.com with ESMTPSA id i21-20020a056a00225500b0063b8f33cb81sm15107078pfu.93.2023.04.28.02.23.56 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 28 Apr 2023 02:23:57 -0700 (PDT) From: Teng Long X-Google-Original-From: Teng Long To: dyroneteng@gmail.com Cc: avarab@gmail.com, git@vger.kernel.org, gitster@pobox.com, sunshine@sunshineco.com, tenglong.tl@alibaba-inc.com Subject: [PATCH v9 6/6] notes.c: introduce "--[no-]stripspace" option Date: Fri, 28 Apr 2023 17:23:34 +0800 Message-ID: <20063beab1893535f03e13b75058d501ed9f2faa.1682671758.git.dyroneteng@gmail.com> X-Mailer: git-send-email 2.40.0.358.g2947072e.dirty In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Teng Long This commit introduces a new option "--[no-]stripspace" to git notes append, git notes edit, and git notes add. This option allows users to control whether the note message need to stripped out. For the consideration of backward compatibility, let's look at the behavior about "stripspace" in "git notes" command: 1. "Edit Message" case: using the default editor to edit the note message. In "edit" case, the edited message will always be stripped out, the implementation which can be found in the "prepare_note_data()". In addition, the "-c" option supports to reuse an existing blob as a note message, then open the editor to make a further edition on it, the edited message will be stripped. This commit doesn't change the default behavior of "edit" case by using an enum "notes_stripspace", only when "--no-stripspace" option is specified, the note message will not be stripped out. If you do not specify the option or you specify "--stripspace", clearly, the note message will be stripped out. 2. "Assign Message" case: using the "-m"/"-F"/"-C" option to specify the note message. In "assign" case, when specify message by "-m" or "-F", the message will be stripped out by default, but when specify message by "-C", the message will be copied verbatim, in other word, the message will not be stripped out. One more thing need to note is "the order of the options matter", that is, if you specify "-C" before "-m" or "-F", the reused message by "-C" will be stripped out together, because everytime concat "-m" or "-F" message, the concated message will be stripped together. Oppositely, if you specify "-m" or "-F" before "-C", the reused message by "-C" will not be stripped out. This commit doesn't change the default behavior of "assign" case by extending the "stripspace" field in "struct note_msg", so we can distinguish the different behavior of "-m"/"-F" and "-C" options when we need to parse and concat the message. Signed-off-by: Teng Long --- Documentation/git-notes.txt | 25 ++- builtin/notes.c | 30 +++- t/t3321-notes-stripspace.sh | 296 +++++++++++++++++++++++++++++++++++- 3 files changed, 332 insertions(+), 19 deletions(-) diff --git a/Documentation/git-notes.txt b/Documentation/git-notes.txt index 59980b21..5f3a9479 100644 --- a/Documentation/git-notes.txt +++ b/Documentation/git-notes.txt @@ -9,10 +9,10 @@ SYNOPSIS -------- [verse] 'git notes' [list []] -'git notes' add [-f] [--allow-empty] [--separator=] [-F | -m | (-c | -C) ] [] +'git notes' add [-f] [--allow-empty] [--separator=] [--[no-]stripspace] [-F | -m | (-c | -C) ] [] 'git notes' copy [-f] ( --stdin | [] ) -'git notes' append [--allow-empty] [--separator=] [-F | -m | (-c | -C) ] [] -'git notes' edit [--allow-empty] [] +'git notes' append [--allow-empty] [--separator=] [--[no-]stripspace] [-F | -m | (-c | -C) ] [] +'git notes' edit [--allow-empty] [] [--[no-]stripspace] 'git notes' show [] 'git notes' merge [-v | -q] [-s ] 'git notes' merge --commit [-v | -q] @@ -141,20 +141,26 @@ OPTIONS If multiple `-m` options are given, their values are concatenated as separate paragraphs. Lines starting with `#` and empty lines other than a - single line between paragraphs will be stripped out. + single line between paragraphs will be stripped out, + if you wish to keep them verbatim, use `--no-stripspace`. -F :: --file=:: Take the note message from the given file. Use '-' to read the note message from the standard input. Lines starting with `#` and empty lines other than a - single line between paragraphs will be stripped out. + single line between paragraphs will be stripped out, + if you wish to keep them verbatim, use with + `--no-stripspace` option. -C :: --reuse-message=:: Take the given blob object (for example, another note) as the note message. (Use `git notes copy ` instead to - copy notes between objects.) + copy notes between objects.). By default, message will be + copied verbatim, but if you wish to strip out the lines + starting with `#` and empty lines other than a single line + between paragraphs, use with`--stripspace` option. -c :: --reedit-message=:: @@ -170,6 +176,13 @@ OPTIONS (a newline is added at the end as needed). Defaults to a blank line. +--[no-]stripspace:: + Strip leading and trailing whitespace from the note message. + Also strip out empty lines other than a single line between + paragraphs. For lines starting with `#` will be stripped out + in non-editor cases like "-m", "-F" and "-C", but not in + editor case like "git notes edit", "-c", etc. + --ref :: Manipulate the notes tree in . This overrides `GIT_NOTES_REF` and the "core.notesRef" configuration. The ref diff --git a/builtin/notes.c b/builtin/notes.c index e32f2453..6eede305 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -101,14 +101,21 @@ static const char * const git_notes_get_ref_usage[] = { static const char note_template[] = N_("Write/edit the notes for the following object:"); +enum notes_stripspace { + UNSPECIFIED = -1, + NO_STRIPSPACE = 0, + STRIPSPACE = 1, +}; + struct note_msg { - int stripspace; + enum notes_stripspace stripspace; struct strbuf buf; }; struct note_data { int given; int use_editor; + int stripspace; char *edit_path; struct strbuf buf; struct note_msg **messages; @@ -213,7 +220,8 @@ static void prepare_note_data(const struct object_id *object, struct note_data * if (launch_editor(d->edit_path, &d->buf, NULL)) { die(_("please supply the note contents using either -m or -F option")); } - strbuf_stripspace(&d->buf, 1); + if (d->stripspace) + strbuf_stripspace(&d->buf, 1); } } @@ -247,7 +255,9 @@ static void concat_messages(struct note_data *d) append_separator(&d->buf); strbuf_add(&msg, d->messages[i]->buf.buf, d->messages[i]->buf.len); strbuf_addbuf(&d->buf, &msg); - if (d->messages[i]->stripspace) + if ((d->stripspace == UNSPECIFIED && + d->messages[i]->stripspace == STRIPSPACE) || + d->stripspace == STRIPSPACE) strbuf_stripspace(&d->buf, 0); strbuf_reset(&msg); } @@ -265,7 +275,7 @@ static int parse_msg_arg(const struct option *opt, const char *arg, int unset) strbuf_addstr(&msg->buf, arg); ALLOC_GROW_BY(d->messages, d->msg_nr, 1, d->msg_alloc); d->messages[d->msg_nr - 1] = msg; - msg->stripspace = 1; + msg->stripspace = STRIPSPACE; return 0; } @@ -285,7 +295,7 @@ static int parse_file_arg(const struct option *opt, const char *arg, int unset) ALLOC_GROW_BY(d->messages, d->msg_nr, 1, d->msg_alloc); d->messages[d->msg_nr - 1] = msg; - msg->stripspace = 1; + msg->stripspace = STRIPSPACE; return 0; } @@ -318,7 +328,7 @@ static int parse_reuse_arg(const struct option *opt, const char *arg, int unset) msg->buf.len = len; ALLOC_GROW_BY(d->messages, d->msg_nr, 1, d->msg_alloc); d->messages[d->msg_nr - 1] = msg; - msg->stripspace = 0; + msg->stripspace = NO_STRIPSPACE; return 0; } @@ -452,7 +462,7 @@ static int add(int argc, const char **argv, const char *prefix) struct notes_tree *t; struct object_id object, new_note; const struct object_id *note; - struct note_data d = { .buf = STRBUF_INIT }; + struct note_data d = { .buf = STRBUF_INIT, .stripspace = UNSPECIFIED }; struct option options[] = { OPT_CALLBACK_F('m', "message", &d, N_("message"), @@ -472,6 +482,8 @@ static int add(int argc, const char **argv, const char *prefix) OPT__FORCE(&force, N_("replace existing notes"), PARSE_OPT_NOCOMPLETE), OPT_STRING(0, "separator", &separator, N_("separator"), N_("insert between paragraphs")), + OPT_BOOL(0, "stripspace", &d.stripspace, + N_("remove unnecessary whitespace")), OPT_END() }; @@ -625,7 +637,7 @@ static int append_edit(int argc, const char **argv, const char *prefix) const struct object_id *note; char *logmsg; const char * const *usage; - struct note_data d = { .buf = STRBUF_INIT }; + struct note_data d = { .buf = STRBUF_INIT, .stripspace = UNSPECIFIED }; struct option options[] = { OPT_CALLBACK_F('m', "message", &d, N_("message"), N_("note contents as a string"), PARSE_OPT_NONEG, @@ -643,6 +655,8 @@ static int append_edit(int argc, const char **argv, const char *prefix) N_("allow storing empty note")), OPT_STRING(0, "separator", &separator, N_("separator"), N_("insert between paragraphs")), + OPT_BOOL(0, "stripspace", &d.stripspace, + N_("remove unnecessary whitespace")), OPT_END() }; int edit = !strcmp(argv[0], "edit"); diff --git a/t/t3321-notes-stripspace.sh b/t/t3321-notes-stripspace.sh index 89977873..028d825e 100755 --- a/t/t3321-notes-stripspace.sh +++ b/t/t3321-notes-stripspace.sh @@ -32,7 +32,7 @@ test_expect_success 'add note by editor' ' test_cmp expect actual ' -test_expect_success 'add note by specifying single "-m"' ' +test_expect_success 'add note by specifying single "-m", "--stripspace" is the default behavior' ' test_when_finished "git notes remove" && cat >expect <<-EOF && first-line @@ -42,10 +42,26 @@ test_expect_success 'add note by specifying single "-m"' ' git notes add -m "${LF}first-line${MULTI_LF}second-line${LF}" && git notes show >actual && + test_cmp expect actual && + git notes remove && + git notes add --stripspace -m "${LF}first-line${MULTI_LF}second-line${LF}" && + git notes show >actual && test_cmp expect actual ' -test_expect_success 'add note by specifying multiple "-m"' ' +test_expect_success 'add note by specifying single "-m" and "--no-stripspace" ' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + ${LF}first-line${MULTI_LF}second-line + EOF + + git notes add --no-stripspace \ + -m "${LF}first-line${MULTI_LF}second-line${LF}" && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'add note by specifying multiple "-m", "--stripspace" is the default behavior' ' test_when_finished "git notes remove" && cat >expect <<-EOF && first-line @@ -59,9 +75,156 @@ test_expect_success 'add note by specifying multiple "-m"' ' -m "second-line" \ -m "${LF}" && git notes show >actual && + test_cmp expect actual && + git notes remove && + git notes add --stripspace -m "${LF}" \ + -m "first-line" \ + -m "${MULTI_LF}" \ + -m "second-line" \ + -m "${LF}" && + git notes show >actual && test_cmp expect actual ' +test_expect_success 'add notes by specifying multiple "-m" and "--no-stripspace"' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + ${LF} + first-line + ${MULTI_LF} + second-line${LF} + EOF + + git notes add --no-stripspace \ + -m "${LF}" \ + -m "first-line" \ + -m "${MULTI_LF}" \ + -m "second-line" \ + -m "${LF}" && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'add note by specifying single "-F", "--stripspace" is the default behavior' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + first-line + + second-line + EOF + + cat >note-file <<-EOF && + ${LF} + first-line + ${MULTI_LF} + second-line + ${LF} + EOF + + git notes add -F note-file && + git notes show >actual && + test_cmp expect actual && + git notes remove && + git notes add --stripspace -F note-file && + git notes show >actual +' + +test_expect_success 'add note by specifying single "-F" and "--no-stripspace"' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + ${LF} + first-line + ${MULTI_LF} + second-line + ${LF} + EOF + + cat >note-file <<-EOF && + ${LF} + first-line + ${MULTI_LF} + second-line + ${LF} + EOF + + git notes add --no-stripspace -F note-file && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'add note by specifying multiple "-F", "--stripspace" is the default behavior' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + file-1-first-line + + file-1-second-line + + file-2-first-line + + file-2-second-line + EOF + + cat >note-file-1 <<-EOF && + ${LF} + file-1-first-line + ${MULTI_LF} + file-1-second-line + ${LF} + EOF + + cat >note-file-2 <<-EOF && + ${LF} + file-2-first-line + ${MULTI_LF} + file-2-second-line + ${LF} + EOF + + git notes add -F note-file-1 -F note-file-2 && + git notes show >actual && + test_cmp expect actual && + git notes remove && + git notes add --stripspace -F note-file-1 -F note-file-2 && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'add note by specifying multiple "-F" with "--no-stripspace"' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + ${LF} + file-1-first-line + ${MULTI_LF} + file-1-second-line + ${LF} + + ${LF} + file-2-first-line + ${MULTI_LF} + file-2-second-line + ${LF} + EOF + + cat >note-file-1 <<-EOF && + ${LF} + file-1-first-line + ${MULTI_LF} + file-1-second-line + ${LF} + EOF + + cat >note-file-2 <<-EOF && + ${LF} + file-2-first-line + ${MULTI_LF} + file-2-second-line + ${LF} + EOF + + git notes add --no-stripspace -F note-file-1 -F note-file-2 && + git notes show >actual && + test_cmp expect actual +' test_expect_success 'append note by editor' ' test_when_finished "git notes remove" && @@ -221,6 +384,45 @@ test_expect_success 'append notes by specifying multiple "-F"' ' test_cmp expect actual ' +test_expect_success 'append note by specifying multiple "-F" with "--no-stripspace"' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + initial-line + ${LF}${LF} + file-1-first-line + ${MULTI_LF} + file-1-second-line + ${LF} + + ${LF} + file-2-first-line + ${MULTI_LF} + file-2-second-line + ${LF} + EOF + + cat >note-file-1 <<-EOF && + ${LF} + file-1-first-line + ${MULTI_LF} + file-1-second-line + ${LF} + EOF + + cat >note-file-2 <<-EOF && + ${LF} + file-2-first-line + ${MULTI_LF} + file-2-second-line + ${LF} + EOF + + git notes add -m "initial-line" && + git notes append --no-stripspace -F note-file-1 -F note-file-2 && + git notes show >actual && + test_cmp expect actual +' + test_expect_success 'add notes with empty messages' ' rev=$(git rev-parse HEAD) && git notes add -m "${LF}" \ @@ -229,7 +431,7 @@ test_expect_success 'add notes with empty messages' ' test_i18ngrep "Removing note for object" actual ' -test_expect_success 'add note by specifying "-C" , do not stripspace is the default behavior' ' +test_expect_success 'add note by specifying "-C", "--no-stripspace" is the default behavior' ' test_when_finished "git notes remove" && cat >expect <<-EOF && ${LF} @@ -242,10 +444,36 @@ test_expect_success 'add note by specifying "-C" , do not stripspace is the defa cat expect | git hash-object -w --stdin >blob && git notes add -C $(cat blob) && git notes show >actual && + test_cmp expect actual && + git notes remove && + git notes add --no-stripspace -C $(cat blob) && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'reuse note by specifying "-C" and "--stripspace"' ' + test_when_finished "git notes remove" && + cat >data <<-EOF && + ${LF} + first-line + ${MULTI_LF} + second-line + ${LF} + EOF + + cat >expect <<-EOF && + first-line + + second-line + EOF + + cat data | git hash-object -w --stdin >blob && + git notes add --stripspace -C $(cat blob) && + git notes show >actual && test_cmp expect actual ' -test_expect_success 'add notes with "-C" and "-m", "-m" will stripspace all together' ' +test_expect_success 'reuse with "-C" and add note with "-m", "-m" will stripspace all together' ' test_when_finished "git notes remove" && cat >data <<-EOF && ${LF} @@ -269,7 +497,7 @@ test_expect_success 'add notes with "-C" and "-m", "-m" will stripspace all toge test_cmp expect actual ' -test_expect_success 'add notes with "-m" and "-C", "-C" will not stripspace all together' ' +test_expect_success 'add note with "-m" and reuse note with "-C", "-C" will not stripspace all together' ' test_when_finished "git notes remove" && cat >data <<-EOF && @@ -288,4 +516,62 @@ test_expect_success 'add notes with "-m" and "-C", "-C" will not stripspace all test_cmp expect actual ' +test_expect_success 'add note by specifying "-c", "--stripspace" is the default behavior' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + first-line + + second-line + EOF + + echo "initial-line" | git hash-object -w --stdin >blob && + MSG="${LF}first-line${MULTI_LF}second-line${LF}" git notes add -c $(cat blob) && + git notes show >actual && + test_cmp expect actual && + git notes remove && + MSG="${LF}first-line${MULTI_LF}second-line${LF}" git notes add --stripspace -c $(cat blob) && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'add note by specifying "-c" with "--no-stripspace"' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + ${LF}first-line${MULTI_LF}second-line${LF} + EOF + + echo "initial-line" | git hash-object -w --stdin >blob && + MSG="${LF}first-line${MULTI_LF}second-line${LF}" git notes add --no-stripspace -c $(cat blob) && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'edit note by specifying "-c", "--stripspace" is the default behavior' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + first-line + + second-line + EOF + + MSG="${LF}first-line${MULTI_LF}second-line${LF}" git notes edit && + git notes show >actual && + test_cmp expect actual && + git notes remove && + MSG="${LF}first-line${MULTI_LF}second-line${LF}" git notes edit --stripspace && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'edit note by specifying "-c" with "--no-stripspace"' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + ${LF}first-line${MULTI_LF}second-line${LF} + EOF + + MSG="${LF}first-line${MULTI_LF}second-line${LF}" git notes add --no-stripspace && + git notes show >actual && + test_cmp expect actual +' + test_done