Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
228 views
in Technique[技术] by (71.8m points)

git - clang-format on all commits to fix indentations and remove trailing white space

I plan to fix only indentations and trailing spaces on all commits. I do not want to place a .clang-format file in the directory. I do not want to touch bracing too.

The command I have considered should be like

git filter-branch --tree-filter 'clang-format ?????????' --tag-name-filter cat -- --all

How can I do that?

Requirements:

  • No harm to the .git folder.
  • IndentWidth: 2
  • Remove all trailing white spaces
  • No other change to the file (e.g. brace open/close locations).
question from:https://stackoverflow.com/questions/66055292/clang-format-on-all-commits-to-fix-indentations-and-remove-trailing-white-space

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

From the Git side: the filter-branch command1 works in principle by:

  • extracting each commit, one at a time, into a temporary directory;
  • running your filter(s) in that temporary directory on that extracted commit; and then
  • building a new replacement commit from the results left behind in the directory.

The replacement commits get strung together, one at a time, in the usual way, and when all commits have been filtered, Git updates the various branch and other such references (--all) as needed, with --tag-name-filter deciding the new tag names (for you case this is all correct).

The --tree-filter method, which is by far the slowest filter, uses this approach without any optimizations. Other filters exist to (a) go faster if you don't plan to touch most of the files and/or (b) make changes to things like the commit messages or other metadata, instead of or in addition to the snapshots. There's probably no point in trying to use a more optimal filter as you really do need to get all the files out in order to reformat them. So the thing to take away here is that each clang-format run will be run in a private, temporary directory that contains no Git repository. The $PWD of that command will be this private directory.

To make things go faster, it's a good idea to consider using the -d option to put that private directory in a memory or SSD or otherwise fast-access file system. For instance, if /tmp is an in-memory file system, mkdir /tmp/foo; git filter-branch -d /tmp/foo ... may run much faster than the one without the -d /tmp/foo directive. The default -d is a subdirectory that Git makes within the .git directory; if that's on a slow, but highly reliable, file system, your filter-branch operation will go very slowly.

From the clang-format side: use any -style= options you like. As numerous commenters noted, trailing whitespace stripping is the default (and apparently there are no options to control this at all now).

Note that it would be fine to add a .clang-format file to the temporary directory. If you leave it there, it will be added to each replacement commit. If you remove it again after adding it, the lack of a .clang-format file (because you removed it) will be what is in each commit. If you do nothing, there will or won't be a .clang-format file based on whether there was one in the commit being filtered.

If you decide that, after all, you would like to use a .clang-format file and add it to each commit, note that you will have to copy the file from outside the temporary directory, to the temporary directory, before each run of clang-format, because Git itself clears out the temporary directory between each commit. Note further that you will not know where the temporary directory is,2 so to copy a known file, use a full path: cp /tmp/new-clang-format-file .clang-format && clang-format -style=file, for instance.


1git filter-branch is nominally outdated now, but its replacement, filter-repo, isn't included with Git, so there's a bit of a dilemma here. You can install filter-repo separately, or for this kind of one-time job, you can just live with filter-branch.

2Even with the -d option, Git makes various sub-directories of the directory you specify (it drops a bunch of temporary files in various places for its own purposes).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...