-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[libc++] Add a merge driver that can apply clang-format #73712
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
In preparation for the moment when we'll clang-format the whole code base, this patch adds a script that can be used to rebase patches across clang-format changes mechanically, without requiring manual intervention. See https://discourse.llvm.org/t/rfc-clang-formatting-all-of-libc-once-and-for-all.
@llvm/pr-subscribers-libcxx Author: Louis Dionne (ldionne) ChangesIn preparation for the moment when we'll clang-format the whole code base, this patch adds a script that can be used to rebase patches across clang-format changes mechanically, without requiring manual intervention. See https://discourse.llvm.org/t/rfc-clang-formatting-all-of-libc-once-and-for-all. Full diff: https://github.com/llvm/llvm-project/pull/73712.diff 1 Files Affected:
diff --git a/libcxx/utils/clang-format-merge-driver.sh b/libcxx/utils/clang-format-merge-driver.sh
new file mode 100755
index 000000000000000..6b1a339720d76a4
--- /dev/null
+++ b/libcxx/utils/clang-format-merge-driver.sh
@@ -0,0 +1,38 @@
+#!/usr/bin/env bash
+
+# This script can be installed in .git/config to allow rebasing old patches across
+# libc++'s clang-format of the whole tree. Most contributors should not require that
+# since they don't have many pre-clang-format patches lying around. This script is to
+# make it easier for contributors that do have such patches.
+#
+# The script is installed by running the following from the root of your repository:
+#
+# $ git config merge.libcxx-reformat.name "Run clang-format when rebasing libc++ patches"
+# $ git config merge.libcxx-reformat.driver "libcxx/utils/clang-format-merge-driver.sh %O %A %B %P"
+# $ git config merge.libcxx-reformat.recursive binary
+#
+# This is based on https://github.com/nico/hack/blob/main/notes/auto_git_rebase_across_mechanical_changes.md.
+# Many thanks to Nico Weber for paving the way here.
+
+# 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 $current $base $other
|
This PR was tested with the following script:
|
What's the difference between this and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
General remark: in a bash script, I would always quote all the string substitutions containing file names, just to avoid any trouble ever with spaces in file names. Also, I don't know if you care about clang-format failures?
Chromium seems to have ended up with a Python script for this?
When you install it, this script will be run when you That way you end up not even noticing that you had a "conflict" to resolve, and the rebase just works. |
Yeah, I almost always do this and I don't know why this time around I got lazy. I fixed that now, thanks for the heads up.
I wonder if that's a bit overkill for us. I expect this to be mostly a one-shot deal, I wouldn't really expect this script to stay around after the original clang-format run. I also expect that very few people will actually want to install this merge driver -- basically only contributors who have a lot of patches to rebase across the change, and maybe some downstream integrators will install it as a one-shot thing to deal with the large initial reformatting. But if you think it's useful for this to be more robust / cross-platform, I can easily migrate to Python. |
Bash is fine for me. I agree this merge driver will only occasionally be needed. In fact, it would not be bad if you could enable it for individual |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
I'll merge this now to make it easier for contributors to play around with the script and see if they encounter issues with it. |
In preparation for the moment when we'll clang-format the whole code base, this patch adds a script that can be used to rebase patches across clang-format changes mechanically, without requiring manual intervention.
See https://discourse.llvm.org/t/rfc-clang-formatting-all-of-libc-once-and-for-all.