Git convert between tabs and spaces but only sometimes

蹲街弑〆低调 提交于 2021-02-07 18:27:44

问题


First, I'm a newbie to git. Like, I could barely tell a cache from an index if it hit me in the staging area. Or something like that. With that out of the way, my problem is this:

Suppose I want to work on a project whose coding style mandates spaces for indentation, but I like tabs. It seems that I can use the clean and smudge features, but there's a catch. The coding style is not followed consistently, and there some files that mix tabs and spaces on the same line. Thus a naïve approach would result in me making a one line change, but accidentally creating a massive commit which brings the project into full compliance with its own standards. This would be great except that the diffs would be less useful so I end up with new enemies.

So the question is: is there a way to get this magic working in such a way that if I don't touch a file, it stays out of the picture? (I'm willing to take full responsibility for the whitespace of files I do touch, even if I change only a single character.)

EDIT: Okay, I just in-accepted the answer I accepted yesterday. I'm pretty sure this is very rude of me. My excuse is that I only got around to testing it today. Since apparently two people misunderstood me already, let me be clear on what I actually did, so maybe someone can tell me if I'm being confused and/or confusing.

$ ls -a
.  ..  t.txt
$ hd t.txt # file contains 3 bytes: a tab, a capital A, and a newline
00000000  09 41 0a                                          |.A.|
00000003
$ git init
Initialized empty Git repository in /home/marvy/test/.git/
$ git config --local git config --local user.name me
$ git config --local user.email me@example.com
$ git add t.txt
$ git commit
[master (root-commit) 959bf99] testing cleverness of git status
 1 file changed, 1 insertion(+)
 create mode 100644 t.txt
$ echo '*.txt filter=tabspace' > .git/info/attributes
$ cat .git/info/attributes
*.txt filter=tabspace
$ git config --local filter.tabspace.smudge unexpand
$ git config --local filter.tabspace.clean expand
$ rm t.txt
$ git checkout t.txt
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   t.txt

no changes added to commit (use "git add" and/or "git commit -a")
$ git help --stackoverflow

As we can see here, git status reports that t.txt is modified, even though I just checked it out. If you run git diff, it will claim I want to convert tabs to spaces. Am I doing something wrong?


回答1:


You could use a pre-commit hook and only loop through your edited files and replaces the tabs with spaces. Something like the below:

FILES=`git status -s -uno | egrep '^M' | sed 's/^M//'`

for FILE in $FILES
do
    (sed -i 's/[[:space:]]*$//' "$FILE" > /dev/null 2>&1 || sed -i '' -E 's/[[:space:]]*$//' "$FILE")
fi



回答2:


The best way to do it is to use script with smudge-clean.

smudge-clean

Smudge/Clean are filters which runs wherever a file is passed through the stage area and those filters will modify the file by executing the given script.

Using smudge and clean will touch only the files you pass through the staging area.


For example (unix sample): If you are unfamiliar with uexpand/unuexpand read about it here

~/.gitconfig

# filters to convert between tabs to spaces
[filter "tabspace"]
    smudge = unexpand --tabs=2 --first-only
    clean = expand --tabs=2 --initial

~/.gitattributes

*.txt  filter=tabspace

Now any time you add/checkout files they will be converted based upon your configuration.

You can also take a look on this project in github




回答3:


Setting up the repository:

  1. Fetch the repository.
  2. Merge to your local master branch.

Make the big change:

  1. You can change the entire repository if you like. do whatever you want and whatever you need to do. make that one line change which changes everything. But only add the files which you yourself have touched to the "staging area". In other words you'll have to manually add those files: git add FilesYouWantToAdd.txt and any other files you are responsible for. Don't add the files you are not responsible for to the staging area.

    git commit -m 'alter spaces to tabs' // adding only the files you are responsible for.

    git push

and you're done.

Discard the other changes:

because nothing substantial in the rest of the files has changed you can simply discard those changes.

git reset HEAD .

It's actually quite simple. Hope this helps.

EDIT:



来源:https://stackoverflow.com/questions/44770689/git-convert-between-tabs-and-spaces-but-only-sometimes

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!