From patchwork Sat May 27 07:57:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Teng Long X-Patchwork-Id: 13257577 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 93204C77B73 for ; Sat, 27 May 2023 07:58:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232177AbjE0H6J (ORCPT ); Sat, 27 May 2023 03:58:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46468 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231831AbjE0H6H (ORCPT ); Sat, 27 May 2023 03:58:07 -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 1893BBB for ; Sat, 27 May 2023 00:58:06 -0700 (PDT) Received: by mail-pf1-x42b.google.com with SMTP id d2e1a72fcca58-64d1a0d640cso1331645b3a.1 for ; Sat, 27 May 2023 00:58:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1685174285; x=1687766285; 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=2nr2o2k4M7iYJ0FlpNlzTlipEOBZWJbJ+J5FjSFWFzY=; b=oR2Xzsh9iBV/Y4BfXdXG1VZ9I+AM3/fdRKs4M4qaiXUGM5Vzow2jZkEqC7Svs/3uMI o2iW9gE/LfAvH6fJUk6W3nz9Ooa+PvC3IBoUz8IyDZsrfZNTIhuwR18bwDYEhCRFMvXn cMa+jrq1ud5yDvxG8WtDWJ2rF6aaBDuxvbFaONVT/0FOc7EACz6PyFDld8SQRlJaLmBY HcmcN7OAlvG+lLirx41MD8AToMpuutZ/bLdA/SlKECe4c+oq6Pd9euScYOdiqdZovqlv 8YXIIc9wTyvaFQLPzWaFuDmk6GIuxy8j0R30dTPFHY0hNjXGzn3piTDrMaS2ykKQ6OMC I8rQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1685174285; x=1687766285; 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=2nr2o2k4M7iYJ0FlpNlzTlipEOBZWJbJ+J5FjSFWFzY=; b=EDuoaC0ZvCF7/gYo7A7jGX4FGJzn2byJnZUul0TjyxlGxvEzbhvdqTBZc1NjSoMhmx HYdAIvp8x40Mni4cLzYpSiSof9uX5gJOOPwQKk6IQ28aCdO/46IaL6ydfhOuWklk/7kC bpHJGzHAev6WRcVHB7Mhh0JnZ/jwAviJP0NBXW1R5ZETy1EEBdu8QJEjxxfG+qBYLaH0 5LaGdhsCAkAmsW9Jc6+1BK4edgXbQk1raDrGDPskX/VfkyImltPQt3u9HNhX0Hjg6bp4 I5abbHEWfL2mLnFi79+ryDyTNN7Zttjfbq41dR/A36mRy2t1StkZ3NAibK1wONrX3432 uMAw== X-Gm-Message-State: AC+VfDxROA+EVuYwME3TfaHIP8+cyIXh5CueIp2xVZFLn/yHW6Tv6AOR T6qQ2hoMFwCyfuOpSH09Qa4= X-Google-Smtp-Source: ACHHUZ5Z8HNqoyobOiSg8l78gOhXoYBAJf+NQXzNJ+NOsKQUOLybNdvH6zXnJ8uAt7MEeEJzakf6DQ== X-Received: by 2002:a17:903:234f:b0:1ae:3e5b:31b1 with SMTP id c15-20020a170903234f00b001ae3e5b31b1mr6508301plh.9.1685174285410; Sat, 27 May 2023 00:58:05 -0700 (PDT) Received: from localhost.localdomain ([47.246.101.60]) by smtp.gmail.com with ESMTPSA id t4-20020a170902b20400b001a6b2813c13sm4355239plr.172.2023.05.27.00.58.03 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 27 May 2023 00:58:05 -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, peff@peff.net, code@khaugsbakk.name Subject: [PATCH v11 1/7] notes.c: cleanup 'strbuf_grow' call in 'append_edit' Date: Sat, 27 May 2023 15:57:48 +0800 Message-ID: <0634434e2a3e40ef4af5013349202491d55fe1d7.1685174012.git.dyroneteng@gmail.com> X-Mailer: git-send-email 2.40.0.356.g367cb1d4 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 Sat May 27 07:57:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Teng Long X-Patchwork-Id: 13257578 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 D4A1FC7EE23 for ; Sat, 27 May 2023 07:58:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232202AbjE0H6L (ORCPT ); Sat, 27 May 2023 03:58:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46478 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229472AbjE0H6J (ORCPT ); Sat, 27 May 2023 03:58:09 -0400 Received: from mail-pl1-x631.google.com (mail-pl1-x631.google.com [IPv6:2607:f8b0:4864:20::631]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4338CB2 for ; Sat, 27 May 2023 00:58:08 -0700 (PDT) Received: by mail-pl1-x631.google.com with SMTP id d9443c01a7336-1ae615d5018so11098815ad.1 for ; Sat, 27 May 2023 00:58:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1685174288; x=1687766288; 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=zRtZhiOscnHYIF+GSWIRgKUMfl3a8JNIZfaVTNPVpd4=; b=meUoC0Ek5yob1BYul0i9LFsYO9zVsIylLwBMJhr3Su4B/SlnH0wAapQWkT/yqOfbgF EClJp06b3TSw1v9Rg+Nv7LFtuOdodBgbBsiBlc3Alk0jC5sS//kwgs6Al2paW49pXrQf ZpAOh52CpXiMQ2egIcF87GQGHKE6ID22syLajuMgzEP6qY1Z6GiuB5qZoYr1n4T+6GoI wSHIAV1yfds6X1ngZRAiRKwIkxvPLAL9QnJS0RYluBJdr/3ffjYWRj2JQk7SQfqyob6M FfBovm6eVnmB2YE7kRLK+xI5Y3finjFava9HgR0yBJFEiF/QoNqAvXKxLW3fmD5tE8Lg S3Kg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1685174288; x=1687766288; 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=zRtZhiOscnHYIF+GSWIRgKUMfl3a8JNIZfaVTNPVpd4=; b=GZdcRxO3cZpzPsb2BqjZh41PjfhN0cKNttoLr5ixGnVjp0Sx1rDJggsxMSUdTKt8dN sVhDMsUVI0u7HYqkyN+Q2YPNio1u+C/TNvOzPbc9nl5TTiFGSF8M0Dd1peKRNj3zuuZT KPaAy9Kr+6Uq1ZTV8fKvUTegMiSZ9PAt+i83eQliGIOiMXNSr7Qhu+DKT4LN/nvsZTaP PPvfUbUnBoXxgjJDsk25h0cMT0QlPgeoxa9CqOhoB8stODbjgWPFHEir+TGvtIOL8OqN OF0DOItUpXelCMtkIgIngM0SiDstjZYUxKk1VCAYMLz8FumsTV2KJHdzswHfjkJ+vten EI1g== X-Gm-Message-State: AC+VfDyu/qHMhzumiPhA6SWFFc6Ix+7oUQmL7lO/AAU8+mNBdFnfMGJ1 4tvkfpA14wzuAT1hEzyEXbA= X-Google-Smtp-Source: ACHHUZ64rI5qz9OAuCAjarfZB7sM3jVkW4lTUCzExuE+FJ+4cZJG36BPkbCKyDrrcolUUvPzioT94g== X-Received: by 2002:a17:902:f551:b0:1ae:e84:268d with SMTP id h17-20020a170902f55100b001ae0e84268dmr6616245plf.25.1685174287676; Sat, 27 May 2023 00:58:07 -0700 (PDT) Received: from localhost.localdomain ([47.246.101.60]) by smtp.gmail.com with ESMTPSA id t4-20020a170902b20400b001a6b2813c13sm4355239plr.172.2023.05.27.00.58.05 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 27 May 2023 00:58:07 -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, peff@peff.net, code@khaugsbakk.name Subject: [PATCH v11 2/7] notes.c: use designated initializers for clarity Date: Sat, 27 May 2023 15:57:49 +0800 Message-ID: <4ad7840584191d6bbb3fcba72887aa569c797a15.1685174012.git.dyroneteng@gmail.com> X-Mailer: git-send-email 2.40.0.356.g367cb1d4 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 Sat May 27 07:57:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Teng Long X-Patchwork-Id: 13257579 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 EF5C0C77B7E for ; Sat, 27 May 2023 07:58:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232446AbjE0H6P (ORCPT ); Sat, 27 May 2023 03:58:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46496 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232292AbjE0H6L (ORCPT ); Sat, 27 May 2023 03:58:11 -0400 Received: from mail-pg1-x535.google.com (mail-pg1-x535.google.com [IPv6:2607:f8b0:4864:20::535]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A0664BB for ; Sat, 27 May 2023 00:58:10 -0700 (PDT) Received: by mail-pg1-x535.google.com with SMTP id 41be03b00d2f7-5343c3daff0so996945a12.0 for ; Sat, 27 May 2023 00:58:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1685174290; x=1687766290; 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=0t8lonkVbMdX7sCPgT5hTlbZHTOi68tTUL0y2xxNzlo=; b=Alq6pqq2a+pBLyN8fGuO4k5/z93xWqMfMRDvvVLhGTT3Do+TlbB5KUH3JHO05SAzEG rI75FtfCx2I9VdYcQl6mHJHHnVm7xiXqxEe8ixiBfErOh+HfHfdRyOtWzfKwiUu1IZBt khPCXxSOCUj+LOsMR5kJbugDkHhB45TEflGajSsa5sXuffu6HJ4tvdB0ZjI/GdEWZPnY qBNjG8F37T3uh4HnyK+xa8wT/UyVBEvYQeie1vHygSJxLTWFUzLgGxE4ET+HeueMDv9v mr5fO29wIQpYkuQb/jFhjcD5IvgZsrmz3U76HashJwQZBO4+mquagcQKs6rxH8Zses7Y 8ksQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1685174290; x=1687766290; 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=0t8lonkVbMdX7sCPgT5hTlbZHTOi68tTUL0y2xxNzlo=; b=SpTP76LjM+H+gwQ27NTlo9+QLD+xjOAgNBnllqR+PrHIS46si3rUiNW/SMjW2ObO0g DHUHVlZuM6HBbdsmpib3lGYjmyXen/wS5gsufHNu3fu0V5Jp81K7mPO8pfsVI1fYtNPt G3hU/7F2CmUmeSH//d1Uo1CFIXsWxRrVFO0EdhhUQZzJ3KR7nzOxOdBELHhMYCDOJZ6R wH9U2C/Y8h1s0KtdrTsPoro7kHI32xJ9tX1PjFT3bssqNM3yI4XMiRjxSHpc8eMvUpNl kAREufYrOzCqAkJiFfBxr0vr7eoysXDDrW2d4/5+2lSmIqCFtu8UHmuU3unde2q0a+dH zSag== X-Gm-Message-State: AC+VfDza3GhjwCgqWmsXiYJj420qEJiVjQqnEYoJOCuq34y5XLVkc2b5 71+/CbPjyIjgBy7HckiUqM4= X-Google-Smtp-Source: ACHHUZ59GIUTpaW9Y417vTMdUBKDabDMo1N5Jsv2qGGWcRz4cvEb5XWocqK3z1VkIWD0Y3Lbvi07jQ== X-Received: by 2002:a17:903:2305:b0:1af:d78f:13f1 with SMTP id d5-20020a170903230500b001afd78f13f1mr6147261plh.49.1685174289946; Sat, 27 May 2023 00:58:09 -0700 (PDT) Received: from localhost.localdomain ([47.246.101.60]) by smtp.gmail.com with ESMTPSA id t4-20020a170902b20400b001a6b2813c13sm4355239plr.172.2023.05.27.00.58.07 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 27 May 2023 00:58:09 -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, peff@peff.net, code@khaugsbakk.name Subject: [PATCH v11 3/7] t3321: add test cases about the notes stripspace behavior Date: Sat, 27 May 2023 15:57:50 +0800 Message-ID: X-Mailer: git-send-email 2.40.0.356.g367cb1d4 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 Sat May 27 07:57:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Teng Long X-Patchwork-Id: 13257580 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 93690C77B73 for ; Sat, 27 May 2023 07:58:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232679AbjE0H6X (ORCPT ); Sat, 27 May 2023 03:58:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46552 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232438AbjE0H6P (ORCPT ); Sat, 27 May 2023 03:58:15 -0400 Received: from mail-pl1-x630.google.com (mail-pl1-x630.google.com [IPv6:2607:f8b0:4864:20::630]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0F3FCBB for ; Sat, 27 May 2023 00:58:13 -0700 (PDT) Received: by mail-pl1-x630.google.com with SMTP id d9443c01a7336-1b01d3bb571so6516025ad.2 for ; Sat, 27 May 2023 00:58:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1685174292; x=1687766292; 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=4MIdCJPgbftZuC0YWb5J5zo2MYl/+/KEdtnXmCOmhRQ=; b=At3nRj6lgcVoMWAL0j5Ju8wA+IeidlN9PEqa8PwWUz8iY6kyzmgL8NJztLXiT+du5D 9Q1kLC5C4LAPPGym9c44E3ogDxbV/j7tyuIpOt4s2EAvz9bTmDGQF88GLV9vLd9KOVi3 Q3IHcf+aIN94PSW7x2NMmmt33k7a9C9Ak5jWHgN5jmW8YhnqbIpK80ApzncuBIN06gTz QI9OtOtn5iaP6LahUSo/zapGkRYjSCa7/iN3M11YJLwI4mn43ymz2c79R5BZs8Js5REB RGRD2nDZETwOYmPZaU/q5M8HHTyBJzj2GpnP8XQCs3TZ1smj43TOOmV/aaRYiev9NWA0 BzZw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1685174292; x=1687766292; 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=4MIdCJPgbftZuC0YWb5J5zo2MYl/+/KEdtnXmCOmhRQ=; b=Dlmji0HyiIX1O0C00kS+iP6iagMn95C2aLKAGLFWTPdgifeoD4K2XL8gpdw5Sk6mnh Qv5LU7r/W7ljVMY8vQgMyD1k/ebaFtVcwZf/nITsUiXfSd+KDuoqVl8bgpTgr3ubuOsC rjgqXIq7XzsooK+qmG7MJXLz8V+SGNW/H7C8TgLadcxVNdXJYnLFdCsqMqFN67sSUUWj l+HcKyjaFZIUk5ygTfdNuCVLRXIYKyyaUfljd0FdndHidO2z5rhpEdcWfWL3Yr3VgIzp Rm9y3iA7nA02w8e9vWj2viik9O3UJ4StI5P2lnqzyKJEZhUXxiuBXcq0KXb3lMxWhd9w /AQQ== X-Gm-Message-State: AC+VfDz9O5jZlxu7rMdlaO2A2DIrkj4omJeD2NFioDdel0H1L+yO08a8 IDsnAClt3ITsmNUTdQWRSFg= X-Google-Smtp-Source: ACHHUZ4diG5z7PU1rIhk279fkRKZo+/a0JL4IRX/nGd2L9P/xLiRcFQhgi1tvvgOc968pRV7nsXwYw== X-Received: by 2002:a17:902:8218:b0:1af:bcf7:2bd8 with SMTP id x24-20020a170902821800b001afbcf72bd8mr4178114pln.52.1685174292352; Sat, 27 May 2023 00:58:12 -0700 (PDT) Received: from localhost.localdomain ([47.246.101.60]) by smtp.gmail.com with ESMTPSA id t4-20020a170902b20400b001a6b2813c13sm4355239plr.172.2023.05.27.00.58.10 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 27 May 2023 00:58:12 -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, peff@peff.net, code@khaugsbakk.name Subject: [PATCH v11 4/7] notes.c: introduce '--separator=' option Date: Sat, 27 May 2023 15:57:51 +0800 Message-ID: <367cb1d465755b401f71b8ac752992689879a699.1685174012.git.dyroneteng@gmail.com> X-Mailer: git-send-email 2.40.0.356.g367cb1d4 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 | 109 ++++++++++++++++++++++++------- t/t3301-notes.sh | 126 ++++++++++++++++++++++++++++++++++++ 3 files changed, 227 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..d8a39fe2 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,97 @@ static void write_note_data(struct note_data *d, struct object_id *oid) } } +static void insert_separator(struct strbuf *message, size_t pos) +{ + size_t sep_len = strlen(separator); + if (sep_len && separator[sep_len - 1] == '\n') + strbuf_insertstr(message, pos, 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 +454,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 +471,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 +484,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 +642,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 +657,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 +684,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 Sat May 27 07:57:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Teng Long X-Patchwork-Id: 13257581 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 93AC0C7EE23 for ; Sat, 27 May 2023 07:58:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232762AbjE0H6Z (ORCPT ); Sat, 27 May 2023 03:58:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46584 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232566AbjE0H6R (ORCPT ); Sat, 27 May 2023 03:58:17 -0400 Received: from mail-pl1-x631.google.com (mail-pl1-x631.google.com [IPv6:2607:f8b0:4864:20::631]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4F59D13A for ; Sat, 27 May 2023 00:58:15 -0700 (PDT) Received: by mail-pl1-x631.google.com with SMTP id d9443c01a7336-1ae8ecb4f9aso10390395ad.1 for ; Sat, 27 May 2023 00:58:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1685174295; x=1687766295; 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=GpYXsiqt088lZOJgZhTZ5Kd3lqo13aCD386khd6uI88=; b=A1GZY/R2QJK853fvv0J24cXDQKTLVUi8UNm84PxZDKsumQBIoK3HmfRHSXudDymKVo 7ouFkVkWG6QLA6WxuklkF758Jnr7JkY4fLsJbv9VKjJMZTjq9b7kwvOhQjOvKhVIYkE/ KonKR8ot1mu12fHd6Z54jBjVfwwJcABVHZpneDszKL0Q4vR63LhPXSS0Y8go/I3/XY58 i96ZNLjlz2fd6aK+No2xBh04fwhKOhwmTK9TcDOEHXPtmQPDudZ1suTOD9NubWGAvPGQ cY2AOR/g+uY7RlaFK/2UHIM6k+YebmivgrPFuNviHEfEEsCORGDbsbAqvZ17TztzPY+y jA5A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1685174295; x=1687766295; 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=GpYXsiqt088lZOJgZhTZ5Kd3lqo13aCD386khd6uI88=; b=FQYN+1XqjeIpsptTtTzShNzQ5h8tCxpaeOzumkJXv1HPOibm39XAy4v9v3CDB/3cNL QIhR5oSqiRXIsRwrnzplG1hvaAouwLa9JgViCScpCwFQNtQr/FRaFwrVxzUAXHgeUWs4 fDA7wMHsL/HnSOu+rCYHBcCQvmokJcpPMpQasUSI0Zw/kfi+U4C9caISo12VM9d/k2UK cJxcLPVFsKGamAfJkkNYw86pTPRbwE9NYiIRuvEiMSmkYd6aijTWFeDVgTxyo7i+eNtD Iuf+8KWU+Nkd6bzpqDiEvbaDAmS8GYvOcAnOw0dqiYrIpe7K2ol2MBx6WNbtSlg40z79 aqDw== X-Gm-Message-State: AC+VfDyXy26MNxLa85qbPK81FYhi2fM3uXEjobDcKro08/pcgLdGkbQp VKp96/C7L89y1Jy5Yz3eH4Y= X-Google-Smtp-Source: ACHHUZ6iWbmL0CuEF7XigcwgqJidrT1zcllp/UMBG4iqYj5uZsgb3F2btueaJ0fsXRI1T2hm8RBCXw== X-Received: by 2002:a17:903:41cc:b0:1ab:675:3e0c with SMTP id u12-20020a17090341cc00b001ab06753e0cmr5993522ple.33.1685174294787; Sat, 27 May 2023 00:58:14 -0700 (PDT) Received: from localhost.localdomain ([47.246.101.60]) by smtp.gmail.com with ESMTPSA id t4-20020a170902b20400b001a6b2813c13sm4355239plr.172.2023.05.27.00.58.12 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 27 May 2023 00:58:14 -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, peff@peff.net, code@khaugsbakk.name Subject: [PATCH v11 5/7] notes.c: append separator instead of insert by pos Date: Sat, 27 May 2023 15:57:52 +0800 Message-ID: <4ba62a48ec56b43f859fce0eb0d88528f6873edb.1685174012.git.dyroneteng@gmail.com> X-Mailer: git-send-email 2.40.0.356.g367cb1d4 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 | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/builtin/notes.c b/builtin/notes.c index d8a39fe2..b2804479 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -229,13 +229,13 @@ 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) { size_t sep_len = strlen(separator); if (sep_len && separator[sep_len - 1] == '\n') - strbuf_insertstr(message, pos, separator); + 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) @@ -245,7 +245,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) @@ -680,14 +680,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 Sat May 27 07:57:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Teng Long X-Patchwork-Id: 13257582 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 16CA9C77B7E for ; Sat, 27 May 2023 07:58:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232772AbjE0H6c (ORCPT ); Sat, 27 May 2023 03:58:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46508 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232641AbjE0H6X (ORCPT ); Sat, 27 May 2023 03:58:23 -0400 Received: from mail-pg1-x530.google.com (mail-pg1-x530.google.com [IPv6:2607:f8b0:4864:20::530]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7FA2519D for ; Sat, 27 May 2023 00:58:17 -0700 (PDT) Received: by mail-pg1-x530.google.com with SMTP id 41be03b00d2f7-5346d150972so1384018a12.3 for ; Sat, 27 May 2023 00:58:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1685174297; x=1687766297; 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=tk4TVWNvEmzhjYre+DJFqMUnHgnfZ1PoAcK85HVfuEU=; b=SKHOuCQfqzurbL6y5OBzfIjDmLcwalTpYTRZo6KX4Z582InXzMJss1vUxW6R1eDb5l bgIhzA53QehwXHL95Mc5qPI2SSp9+zJecDAMNXzYEHwTd1tMQtGIn0m4E6PJoMn8FL+N wDGYcXJixH1lnECTEphQYEpCesfgkOc70I8q7vqdRUsZEc94ERES6pYsHfpfl9Xyk4WY /r7T33WWEG4VGo0ebBDXDdm7dZPelpp93GPV8GliilrwS2Do8zbfs1QctfjjaTcin5Ii pOywgt2whVy/SbyJBxVrkhPym6V9CgSh4xJuOeX/3XhKH3HJEeND+2q2WNs+HIwz3R/m v9mw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1685174297; x=1687766297; 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=tk4TVWNvEmzhjYre+DJFqMUnHgnfZ1PoAcK85HVfuEU=; b=UCk/qq8S9svfHEO/09NxUEOsITNi5kJuOAgn7cbpkwjBoY3jDzMJ5zAFyiG5XO9ext 9bt5RhFiZS6pRmqFtFNmoecoVqhnYcOcsi/ffPb+r4++IIw2NtwVXT2NAnzY6A40F7K/ dgywMZbKV5E7uNJ8ueiXFuzJiu8mJ7prbwIvGY72ElSmlrTTCD5MZQkYqqa5g4mKsk/A INr29lJSPN3xS0SIv4ayi/AWCu/CXaMGb6Ckx8x8+KD3zdiC5CLXjG6f8pY244sGjWfi Tgsl6TG6A9FSWL4k8lwUB12Pf5WZx01TjjLF9SrM07M1lgceqWBlRTtytcMHpHM1m0sU 6udw== X-Gm-Message-State: AC+VfDzQnDGOHtGYezKi55jeXbEKPPKsNCSfn0yVP/H72lNafvhHt9vY fV8S3UUS3byx0PxT67g4B+0= X-Google-Smtp-Source: ACHHUZ7BLH9L1pOXpbQ2JFJuespm5lz2y4jA0Vi7QnuWR/jgYM6IYRo6KT89iwDCWENwpzCjk/PfIQ== X-Received: by 2002:a17:902:e886:b0:1ae:8e80:ba89 with SMTP id w6-20020a170902e88600b001ae8e80ba89mr5922816plg.0.1685174297129; Sat, 27 May 2023 00:58:17 -0700 (PDT) Received: from localhost.localdomain ([47.246.101.60]) by smtp.gmail.com with ESMTPSA id t4-20020a170902b20400b001a6b2813c13sm4355239plr.172.2023.05.27.00.58.15 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 27 May 2023 00:58:16 -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, peff@peff.net, code@khaugsbakk.name Subject: [PATCH v11 6/7] notes.c: introduce "--[no-]stripspace" option Date: Sat, 27 May 2023 15:57:53 +0800 Message-ID: <19865941bb29c28a690ed3e28fc4f6870e352923.1685174012.git.dyroneteng@gmail.com> X-Mailer: git-send-email 2.40.0.356.g367cb1d4 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 b2804479..2140a697 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); } } @@ -248,7 +256,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); } @@ -266,7 +276,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; } @@ -286,7 +296,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; } @@ -319,7 +329,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; } @@ -453,7 +463,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"), @@ -473,6 +483,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() }; @@ -626,7 +638,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, @@ -644,6 +656,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 From patchwork Sat May 27 07:57:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Teng Long X-Patchwork-Id: 13257583 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 89AF8C77B73 for ; Sat, 27 May 2023 07:58:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232804AbjE0H6h (ORCPT ); Sat, 27 May 2023 03:58:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46546 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232578AbjE0H6Y (ORCPT ); Sat, 27 May 2023 03:58:24 -0400 Received: from mail-pl1-x62e.google.com (mail-pl1-x62e.google.com [IPv6:2607:f8b0:4864:20::62e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5EA581BD for ; Sat, 27 May 2023 00:58:20 -0700 (PDT) Received: by mail-pl1-x62e.google.com with SMTP id d9443c01a7336-1b011cffef2so13409345ad.3 for ; Sat, 27 May 2023 00:58:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1685174299; x=1687766299; 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=T9E2StsDd4XM2e4NNPlwxRBu0P/BIgaVhRv7acUzq8U=; b=MnskAM9xAe+darvH9s3BOGOXxC5n8iNRSRDxumEbPacvAalwYTfSD3uEWGZZe08e7x KJwswMK/w2Yi+DLmnBq/VIn0ut0ejinWkrLk1BtY6IPMgvK9JRg6+HL1cdH7WUaipxYg Xzq5jXL4PwvzEqsWBYY/niP94jz8UwDhAr5quu4/YI3jhP7PXltTGG13QLpEDPaZ0r0V xcbE/jccRCu2Rvqlt1AuLALwjm/7aNL6hUdLvmWx8YncGzeU0qlz8T+ISfpZPgs3QPGy 9lOBUgA9oPEsysiVGIxjWVqujCYsb4VOf2759EgOfkOJnGK8Gq2BT4T4DAE2bKLj/9sz gesQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1685174299; x=1687766299; 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=T9E2StsDd4XM2e4NNPlwxRBu0P/BIgaVhRv7acUzq8U=; b=We5vjCXY7WAApx+tSUqhsJLjshbgVJrM6XYO5SEHIHiawre/W3Ry5b3H3N3ft4uOI3 mYoNe2sDczIXh7nlM6/7LE9Nt2Iig3rw70kgE1xQhJPWdhJGSnqxgLtEV7BL2nM4NyK0 5yzAlSVKk07EhSFPrsG+6oYDHAKacoR2P9dfAOfseImug5p9a0s/8vPJ0CtR/x+Phj9r qjjNeqM+NRgfxZbAuK164Pn/K/YXj7EqqXKrKwAwixdPGOURrHMYI284DEO/c10BnMyH 92y62PbUlRuAmgWrebwc7VAEqCMsZjgCjZqUQejKU5iDiQMWDgTeRHTYHH+eHbnTjedB tF3A== X-Gm-Message-State: AC+VfDyCojtSMjpGeB3Tlkam3j8fUHkZNRbg8K0XnTiGcrytVuHSOBzf 9FlK8+MCsO2b1l/KQwxFn3g= X-Google-Smtp-Source: ACHHUZ57h1Nf1p36WdBpnlBuu6SLZoS4K4cMvdrkHmbduDIsANslazgOAKFkHkFd4PdEMZ65pP8spw== X-Received: by 2002:a17:903:280f:b0:1ac:a6b0:1c87 with SMTP id kp15-20020a170903280f00b001aca6b01c87mr4646210plb.48.1685174299400; Sat, 27 May 2023 00:58:19 -0700 (PDT) Received: from localhost.localdomain ([47.246.101.60]) by smtp.gmail.com with ESMTPSA id t4-20020a170902b20400b001a6b2813c13sm4355239plr.172.2023.05.27.00.58.17 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 27 May 2023 00:58:19 -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, peff@peff.net, code@khaugsbakk.name Subject: [PATCH v11 7/7] notes: introduce "--no-separator" option Date: Sat, 27 May 2023 15:57:54 +0800 Message-ID: <7105778c30102069ffadcdbb7086a62083b4c766.1685174012.git.dyroneteng@gmail.com> X-Mailer: git-send-email 2.40.0.356.g367cb1d4 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Teng Long Sometimes, the user may want to add or append multiple notes without any separator to be added between them. Disscussion: https://public-inbox.org/git/3f86a553-246a-4626-b1bd-bacd8148318a@app.fastmail.com/ Signed-off-by: Teng Long --- Documentation/git-notes.txt | 11 +++++---- builtin/notes.c | 37 ++++++++++++++++++++-------- t/t3301-notes.sh | 49 ++++++++++++++++++++++++++++++++++--- 3 files changed, 79 insertions(+), 18 deletions(-) diff --git a/Documentation/git-notes.txt b/Documentation/git-notes.txt index 5f3a9479..bc1bfa37 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] [--separator=] [--[no-]stripspace] [-F | -m | (-c | -C) ] [] +'git notes' add [-f] [--allow-empty] [--[no-]separator | --separator=] [--[no-]stripspace] [-F | -m | (-c | -C) ] [] 'git notes' copy [-f] ( --stdin | [] ) -'git notes' append [--allow-empty] [--separator=] [--[no-]stripspace] [-F | -m | (-c | -C) ] [] +'git notes' append [--allow-empty] [--[no-]separator | --separator=] [--[no-]stripspace] [-F | -m | (-c | -C) ] [] 'git notes' edit [--allow-empty] [] [--[no-]stripspace] 'git notes' show [] 'git notes' merge [-v | -q] [-s ] @@ -171,10 +171,11 @@ OPTIONS Allow an empty note object to be stored. The default behavior is to automatically remove empty notes. ---separator :: +--[no-]separator, --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. + (a newline is added at the end as needed). If `--no-separator`, no + separators will be added between paragraphs. Defaults to a blank + line. --[no-]stripspace:: Strip leading and trailing whitespace from the note message. diff --git a/builtin/notes.c b/builtin/notes.c index 2140a697..00268e94 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -28,12 +28,12 @@ #include "worktree.h" #include "write-or-die.h" -static char *separator = "\n"; +static const char *separator = "\n"; static const char * const git_notes_usage[] = { N_("git notes [--ref ] [list []]"), - N_("git notes [--ref ] add [-f] [--allow-empty] [--separator=] [-m | -F | (-c | -C) ] []"), + N_("git notes [--ref ] add [-f] [--allow-empty] [--[no-]separator|--separator=] [--[no-]stripspace] [-m | -F | (-c | -C) ] []"), N_("git notes [--ref ] copy [-f] "), - N_("git notes [--ref ] append [--allow-empty] [--separator=] [-m | -F | (-c | -C) ] []"), + N_("git notes [--ref ] append [--allow-empty] [--[no-]separator|--separator=] [--[no-]stripspace] [-m | -F | (-c | -C) ] []"), N_("git notes [--ref ] edit [--allow-empty] []"), N_("git notes [--ref ] show []"), N_("git notes [--ref ] merge [-v | -q] [-s ] "), @@ -239,8 +239,11 @@ static void write_note_data(struct note_data *d, struct object_id *oid) static void append_separator(struct strbuf *message) { - size_t sep_len = strlen(separator); - if (sep_len && separator[sep_len - 1] == '\n') + size_t sep_len = 0; + + if (!separator) + return; + else if ((sep_len = strlen(separator)) && separator[sep_len - 1] == '\n') strbuf_addstr(message, separator); else strbuf_addf(message, "%s%s", separator, "\n"); @@ -249,8 +252,8 @@ static void append_separator(struct strbuf *message) 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) append_separator(&d->buf); @@ -341,6 +344,16 @@ static int parse_reedit_arg(const struct option *opt, const char *arg, int unset return parse_reuse_arg(opt, arg, unset); } +static int parse_separator_arg(const struct option *opt, const char *arg, + int unset) +{ + if (unset) + *(const char **)opt->value = NULL; + else + *(const char **)opt->value = arg ? arg : "\n"; + return 0; +} + static int notes_copy_from_stdin(int force, const char *rewrite_cmd) { struct strbuf buf = STRBUF_INIT; @@ -481,8 +494,10 @@ 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_CALLBACK_F(0, "separator", &separator, + N_(""), + N_("insert between paragraphs"), + PARSE_OPT_OPTARG, parse_separator_arg), OPT_BOOL(0, "stripspace", &d.stripspace, N_("remove unnecessary whitespace")), OPT_END() @@ -654,8 +669,10 @@ 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_CALLBACK_F(0, "separator", &separator, + N_(""), + N_("insert between paragraphs"), + PARSE_OPT_OPTARG, parse_separator_arg), OPT_BOOL(0, "stripspace", &d.stripspace, N_("remove unnecessary whitespace")), OPT_END() diff --git a/t/t3301-notes.sh b/t/t3301-notes.sh index dbadcf13..d734000d 100755 --- a/t/t3301-notes.sh +++ b/t/t3301-notes.sh @@ -382,6 +382,7 @@ test_expect_success 'create note with combination of -m and -F' ' ' test_expect_success 'create note with combination of -m and -F and --separator' ' + test_when_finished git notes remove HEAD && cat >expect-combine_m_and_F <<-\EOF && foo ------- @@ -395,7 +396,22 @@ test_expect_success 'create note with combination of -m and -F and --separator' 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 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 'create note with combination of -m and -F and --no-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" --no-separator && git notes show >actual && test_cmp expect-combine_m_and_F actual ' @@ -541,7 +557,7 @@ test_expect_success 'listing non-existing notes fails' ' test_must_be_empty actual ' -test_expect_success 'append: specify an empty separator' ' +test_expect_success 'append: specify a separator with an empty arg' ' test_when_finished git notes remove HEAD && cat >expect <<-\EOF && notes-1 @@ -555,6 +571,33 @@ test_expect_success 'append: specify an empty separator' ' test_cmp expect actual ' +test_expect_success 'append: specify a separator without arg' ' + 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 as --no-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 --no-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 && @@ -615,7 +658,7 @@ test_expect_success 'append note with combination of -m and -F and --separator' 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 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 '