[llvm] [DRAFT][clang-format] helper script for resolving downstream reformat… (PR #80462)
Paul T Robinson via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 6 10:59:31 PST 2024
https://github.com/pogo59 updated https://github.com/llvm/llvm-project/pull/80462
>From d0295f0af601bf8eb4596a5ed74ef63a8fee42d9 Mon Sep 17 00:00:00 2001
From: Paul Robinson <paul.robinson at sony.com>
Date: Fri, 2 Feb 2024 08:55:27 -0800
Subject: [PATCH 1/2] [DRAFT][clang-format] helper script for resolving
downstream reformat conflicts
---
llvm/utils/git/clang-format-merge-resolver.sh | 51 +++++++++++++++++++
1 file changed, 51 insertions(+)
create mode 100644 llvm/utils/git/clang-format-merge-resolver.sh
diff --git a/llvm/utils/git/clang-format-merge-resolver.sh b/llvm/utils/git/clang-format-merge-resolver.sh
new file mode 100644
index 0000000000000..128e0379a30e4
--- /dev/null
+++ b/llvm/utils/git/clang-format-merge-resolver.sh
@@ -0,0 +1,51 @@
+#!/usr/bin/env bash
+
+# One-time setup:
+# git config mergetool.llvm-reformat.cmd 'llvm/utils/git/clang-format-merge-resolver.sh "$BASE" "$LOCAL" "$REMOTE" "$MERGED" '
+#
+# Usage:
+# If clang-format is not on PATH:
+# export CLANG_FORMAT_PATH=/path/to/clang-format
+# After you have merged a reformatting commit and it has conflicts, run:
+# git mergetool --tool=llvm-reformat
+
+# This script is based on libcxx/utils/clang-format-merge-driver.sh
+# which sadly cannot simply be used.
+
+# Find clang-format the same way code-format-helper.py does.
+if [ -x "$CLANG_FORMAT_PATH" ]; then
+ CLANG_FORMAT=$CLANG_FORMAT_PATH
+else
+ CLANG_FORMAT=`which clang-format`
+ if [ ! $? ]; then
+ exit -1
+ fi
+fi
+
+# Path to the file's contents at the ancestor's version.
+base="$1"
+
+# Path to the file's contents at the current version.
+current="$2"
+
+# Path to the file's contents at the other branch's version (for nonlinear histories, there might be multiple other branches).
+other="$3"
+
+# The path of the file in the repository.
+path="$4"
+
+$CLANG_FORMAT --style=file --assume-filename="$path" < "$base" > "$base.tmp"
+mv "$base.tmp" "$base"
+
+$CLANG_FORMAT --style=file --assume-filename="$path" < "$current" > "$current.tmp"
+mv "$current.tmp" "$current"
+
+$CLANG_FORMAT --style=file --assume-filename="$path" < "$other" > "$other.tmp"
+mv "$other.tmp" "$other"
+
+git merge-file -Lcurrent -Lbase -Lother "$current" "$base" "$other"
+STATUS=$?
+if [ $STATUS ]; then
+ mv "$current" "$path"
+fi
+exit $STATUS
>From 642196bdb7913470cc129370d9e5f8147e7bf09f Mon Sep 17 00:00:00 2001
From: Paul Robinson <paul.robinson at sony.com>
Date: Tue, 6 Feb 2024 10:59:17 -0800
Subject: [PATCH 2/2] Rewrite as a standalone script
---
llvm/utils/git/clang-format-merge-resolver.sh | 96 ++++++++++++-------
1 file changed, 62 insertions(+), 34 deletions(-)
diff --git a/llvm/utils/git/clang-format-merge-resolver.sh b/llvm/utils/git/clang-format-merge-resolver.sh
index 128e0379a30e4..7e2f242810410 100644
--- a/llvm/utils/git/clang-format-merge-resolver.sh
+++ b/llvm/utils/git/clang-format-merge-resolver.sh
@@ -1,51 +1,79 @@
#!/usr/bin/env bash
-# One-time setup:
-# git config mergetool.llvm-reformat.cmd 'llvm/utils/git/clang-format-merge-resolver.sh "$BASE" "$LOCAL" "$REMOTE" "$MERGED" '
-#
# Usage:
# If clang-format is not on PATH:
# export CLANG_FORMAT_PATH=/path/to/clang-format
-# After you have merged a reformatting commit and it has conflicts, run:
-# git mergetool --tool=llvm-reformat
+# Run this script to resolve the formatting conflicts and leave only
+# the non-formatting conflicts for you to resolve manually.
-# This script is based on libcxx/utils/clang-format-merge-driver.sh
-# which sadly cannot simply be used.
+# Find the .git directory.
+GIT_DIR=$(git rev-parse --git-dir)
+
+# Are we in the midst of a merge? If not, this is the wrong tool.
+if [ ! -e $GIT_DIR/MERGE_HEAD ]; then
+ echo Not doing a merge?
+ exit -1
+fi
+
+# Find the "current" "other" and "base" commits.
+# The commit we are merging into.
+read CURRENT < $GIT_DIR/ORIG_HEAD
+# The commit being merged into CURRENT.
+read OTHER < $GIT_DIR/MERGE_HEAD
+# Where it all started.
+BASE=$(git merge-base $CURRENT $OTHER)
+
+# Set up a place to keep temp files.
+MYTEMP=$(mktemp -d)
+trap 'rm -rf $MYTEMP' EXIT
# Find clang-format the same way code-format-helper.py does.
-if [ -x "$CLANG_FORMAT_PATH" ]; then
+if [ -x "$CLANG_FORMAT_PATH" ]
+then
CLANG_FORMAT=$CLANG_FORMAT_PATH
else
- CLANG_FORMAT=`which clang-format`
- if [ ! $? ]; then
+ CLANG_FORMAT=$(which clang-format)
+ if [ ! $? ]
+ then
+ echo clang-format not found on PATH
exit -1
fi
fi
-# Path to the file's contents at the ancestor's version.
-base="$1"
-
-# Path to the file's contents at the current version.
-current="$2"
+# resolve_one_file will perform formatting-conflict resolution on one file.
+# If any conflicts remain, informs the user, otherwise will git-add the
+# resolved file.
+resolve_one_file() {
+ file=$1
+ echo Resolving "$file"...
-# Path to the file's contents at the other branch's version (for nonlinear histories, there might be multiple other branches).
-other="$3"
+ # Get formatted copies of the base, current, and other files.
+ git show "$BASE:$file" | $CLANG_FORMAT --style=file --assume-filename="$file" > "$MYTEMP/base"
+ git show "$OTHER:$file" | $CLANG_FORMAT --style=file --assume-filename="$file" > "$MYTEMP/other"
+ git show "$CURRENT:$file" | $CLANG_FORMAT --style=file --assume-filename="$file" > "$MYTEMP/current"
-# The path of the file in the repository.
-path="$4"
-
-$CLANG_FORMAT --style=file --assume-filename="$path" < "$base" > "$base.tmp"
-mv "$base.tmp" "$base"
-
-$CLANG_FORMAT --style=file --assume-filename="$path" < "$current" > "$current.tmp"
-mv "$current.tmp" "$current"
-
-$CLANG_FORMAT --style=file --assume-filename="$path" < "$other" > "$other.tmp"
-mv "$other.tmp" "$other"
+ # Merge the formatted files and report failures.
+ git merge-file -Lcurrent -Lbase -Lother "$MYTEMP/current" "$MYTEMP/base" "$MYTEMP/other"
+ STATUS=$?
+ if [ $STATUS -lt 0 ]
+ then
+ echo git merge-file failed for "$file"
+ else
+ mv "$MYTEMP/current" "$file"
+ if [ $STATUS -eq 0 ]
+ then
+ git add "$file"
+ else
+ echo Conflicts remain in $file
+ fi
+ fi
+}
-git merge-file -Lcurrent -Lbase -Lother "$current" "$base" "$other"
-STATUS=$?
-if [ $STATUS ]; then
- mv "$current" "$path"
-fi
-exit $STATUS
+# Find all the conflicted files, and operate on each one.
+# `git status --porcelain` identifies conflicted files with 'UU ' prefix.
+# No other prefix is relevant here.
+git status --porcelain | grep '^UU ' | cut -c 4- | \
+ while read -r file
+ do
+ resolve_one_file "$file"
+ done
More information about the llvm-commits
mailing list