From: "brian m. carlson" <sandals@crustytoothpaste.net>
To: <git@vger.kernel.org>
Cc: Jeff King <peff@peff.net>,
Phillip Wood <phillip.wood123@gmail.com>,
Thomas Gummerer <t.gummerer@gmail.com>,
Johannes Schindelin <Johannes.Schindelin@gmx.de>
Subject: [PATCH v5 0/2] Honor .gitattributes with rebase --am
Date: Sun, 25 Aug 2019 23:33:38 +0000 [thread overview]
Message-ID: <20190825233340.10894-1-sandals@crustytoothpaste.net> (raw)
This series makes rebase --am honor the .gitattributes file for
subsequent patches when a patch changes it.
Note that there are two places we load attributes in ll-merge.c, but
this code only handles the one that git am uses. The two cannot be
unified because the one in ll_merge_marker_size intentionally doesn't
load the merge attribute, since it wants to always use the recursive
strategy. Loading it anyway causes t4017 to fail.
Changes from v4:
* Wrap lines in apply.c.
* Handle merge and conflict-marker-size attributes.
* Add tests for am and am -3 in addition to rebase.
Changes from v3:
* Check for both addition and removal of .gitattributes files.
* Switch from "test_config" to "git config".
Changes from v2:
* Rename has_path_suffix to ends_with_path_components.
Changes from v1:
* Add has_path_suffix in a separate commit.
brian m. carlson (2):
path: add a function to check for path suffix
am: reload .gitattributes after patching it
apply.c | 11 ++++++++++
convert.c | 11 +++++++++-
convert.h | 6 ++++++
ll-merge.c | 19 +++++++++++++----
ll-merge.h | 1 +
path.c | 39 +++++++++++++++++++++++++++--------
path.h | 3 +++
t/t3400-rebase.sh | 36 ++++++++++++++++++++++++++++++++
t/t4150-am.sh | 52 +++++++++++++++++++++++++++++++++++++++++++++++
9 files changed, 164 insertions(+), 14 deletions(-)
Range-diff against v4:
1: fa825e4b40 ! 1: 2077a0829e apply: reload .gitattributes after patching it
@@ Metadata
Author: brian m. carlson <sandals@crustytoothpaste.net>
## Commit message ##
- apply: reload .gitattributes after patching it
+ am: reload .gitattributes after patching it
When applying multiple patches with git am, or when rebasing using the
am backend, it's possible that one of our patches has updated a
@@ Commit message
To ensure we write the correct data into the working tree, expire the
cache after each patch that touches a path ending in ".gitattributes".
+ Since we load these attributes in multiple separate files, we must
+ expire them accordingly.
+
+ Verify that both the am and rebase code paths work correctly, including
+ the conflict marker size with am -3.
Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
@@ apply.c: static int apply_patch(struct apply_state *state,
*listp = patch;
listp = &patch->next;
+
-+ if ((patch->new_name && ends_with_path_components(patch->new_name, GITATTRIBUTES_FILE)) ||
-+ (patch->old_name && ends_with_path_components(patch->old_name, GITATTRIBUTES_FILE)))
++ if ((patch->new_name &&
++ ends_with_path_components(patch->new_name,
++ GITATTRIBUTES_FILE)) ||
++ (patch->old_name &&
++ ends_with_path_components(patch->old_name,
++ GITATTRIBUTES_FILE)))
+ flush_attributes = 1;
}
else {
@@ apply.c: static int apply_patch(struct apply_state *state,
strbuf_release(&buf);
## convert.c ##
+@@
+ #include "pkt-line.h"
+ #include "sub-process.h"
+ #include "utf8.h"
++#include "ll-merge.h"
+
+ /*
+ * convert.c - convert a file when checking it out and checking it in.
@@ convert.c: struct conv_attrs {
const char *working_tree_encoding; /* Supported encoding or default encoding if NULL */
};
@@ convert.c: static void convert_attrs(const struct index_state *istate,
+{
+ attr_check_free(check);
+ check = NULL;
++ reset_merge_attributes();
+}
+
int would_convert_to_git_filter_fd(const struct index_state *istate, const char *path)
@@ convert.h: void convert_to_git_filter_fd(const struct index_state *istate,
*
* Streaming conversion support
+ ## ll-merge.c ##
+@@ ll-merge.c: struct ll_merge_driver {
+ char *cmdline;
+ };
+
++static struct attr_check *merge_attributes;
++static struct attr_check *load_merge_attributes(void)
++{
++ if (!merge_attributes)
++ merge_attributes = attr_check_initl("merge", "conflict-marker-size", NULL);
++ return merge_attributes;
++}
++
++void reset_merge_attributes(void)
++{
++ attr_check_free(merge_attributes);
++ merge_attributes = NULL;
++}
++
+ /*
+ * Built-in low-levels
+ */
+@@ ll-merge.c: int ll_merge(mmbuffer_t *result_buf,
+ struct index_state *istate,
+ const struct ll_merge_options *opts)
+ {
+- static struct attr_check *check;
++ struct attr_check *check = load_merge_attributes();
+ static const struct ll_merge_options default_opts;
+ const char *ll_driver_name = NULL;
+ int marker_size = DEFAULT_CONFLICT_MARKER_SIZE;
+@@ ll-merge.c: int ll_merge(mmbuffer_t *result_buf,
+ normalize_file(theirs, path, istate);
+ }
+
+- if (!check)
+- check = attr_check_initl("merge", "conflict-marker-size", NULL);
+-
+ git_check_attr(istate, path, check);
+ ll_driver_name = check->items[0].value;
+ if (check->items[1].value) {
+
+ ## ll-merge.h ##
+@@ ll-merge.h: int ll_merge(mmbuffer_t *result_buf,
+ const struct ll_merge_options *opts);
+
+ int ll_merge_marker_size(struct index_state *istate, const char *path);
++void reset_merge_attributes(void);
+
+ #endif
+
## t/t3400-rebase.sh ##
@@ t/t3400-rebase.sh: test_expect_success 'rebase --am and --show-current-patch' '
)
@@ t/t3400-rebase.sh: test_expect_success 'rebase --am and --show-current-patch' '
test_expect_success 'rebase--merge.sh and --show-current-patch' '
test_create_repo conflict-merge &&
(
+
+ ## t/t4150-am.sh ##
+@@ t/t4150-am.sh: test_expect_success 'am --quit keeps HEAD where it is' '
+ test_cmp expected actual
+ '
+
++test_expect_success 'am and .gitattibutes' '
++ test_create_repo attributes &&
++ (
++ cd attributes &&
++ test_commit init &&
++ git config filter.test.clean "sed -e '\''s/smudged/clean/g'\''" &&
++ git config filter.test.smudge "sed -e '\''s/clean/smudged/g'\''" &&
++
++ test_commit second &&
++ git checkout -b test HEAD^ &&
++
++ echo "*.txt filter=test conflict-marker-size=10" >.gitattributes &&
++ git add .gitattributes &&
++ test_commit third &&
++
++ echo "This text is smudged." >a.txt &&
++ git add a.txt &&
++ test_commit fourth &&
++
++ git checkout -b removal HEAD^ &&
++ git rm .gitattributes &&
++ git add -u &&
++ test_commit fifth &&
++ git cherry-pick test &&
++
++ git checkout -b conflict third &&
++ echo "This text is different." >a.txt &&
++ git add a.txt &&
++ test_commit sixth &&
++
++ git checkout test &&
++ git format-patch --stdout master..HEAD >patches &&
++ git reset --hard master &&
++ git am patches &&
++ grep "smudged" a.txt &&
++
++ git checkout removal &&
++ git reset --hard &&
++ git format-patch --stdout master..HEAD >patches &&
++ git reset --hard master &&
++ git am patches &&
++ grep "clean" a.txt &&
++
++ git checkout conflict &&
++ git reset --hard &&
++ git format-patch --stdout master..HEAD >patches &&
++ git reset --hard fourth &&
++ test_must_fail git am -3 patches &&
++ grep "<<<<<<<<<<" a.txt
++ )
++'
++
+ test_done
next reply other threads:[~2019-08-25 23:34 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-08-25 23:33 brian m. carlson [this message]
2019-08-25 23:33 ` [PATCH v5 1/2] path: add a function to check for path suffix brian m. carlson
2019-08-25 23:33 ` [PATCH v5 2/2] am: reload .gitattributes after patching it brian m. carlson
2019-08-28 11:30 ` Johannes Schindelin
2019-08-29 23:09 ` brian m. carlson
2019-08-30 19:46 ` Johannes Schindelin
2019-08-26 15:11 ` [PATCH v5 0/2] Honor .gitattributes with rebase --am Phillip Wood
2019-09-02 22:39 ` [PATCH v6 " brian m. carlson
2019-09-02 22:39 ` [PATCH v6 1/2] path: add a function to check for path suffix brian m. carlson
2019-09-02 22:39 ` [PATCH v6 2/2] am: reload .gitattributes after patching it brian m. carlson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190825233340.10894-1-sandals@crustytoothpaste.net \
--to=sandals@crustytoothpaste.net \
--cc=Johannes.Schindelin@gmx.de \
--cc=git@vger.kernel.org \
--cc=peff@peff.net \
--cc=phillip.wood123@gmail.com \
--cc=t.gummerer@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).