Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Revert file permission changes in local git repository.. Very useful when you change permissions due to working on a samba share. Lifted from: http://stackoverflow.com/questions/2517339/git-how-to-recover-the-file-permissions-git-thinks-the-file-should-be
git diff -p \
| grep -E '^(diff|old mode|new mode)' \
| sed -e 's/^old/NEW/;s/^new/old/;s/^NEW/new/' \
| git apply
@Dzenly
Copy link

Dzenly commented Mar 8, 2018

Just in case -p option is not about 'permissions', it is about 'patch'. Also this option is used by default, so can be omited.
https://git-scm.com/docs/git-diff

Also in pointed topic, there is an improvement:

git diff -p -R --no-color \
    | grep -E "^(diff|(old|new) mode)" --color=never  \
    | git apply

@hadaytullah
Copy link

hadaytullah commented Jun 17, 2019

Thanks! appreciate the help.

@abilogos
Copy link

abilogos commented Oct 13, 2019

thanks. very helpful for me.
it just applies (revert) only file mode changes (diff|(old|new) mode).
Thanks a lot.

@RaphiStein
Copy link

RaphiStein commented Dec 31, 2019

Any ideas on how to filter out files that have changes in their content?
For example, I want all the files with permissions changes but not if they also have changes in their content

@bene20
Copy link

bene20 commented Mar 16, 2020

Excelent!
If you have configured an external diff tool, i recommend you to add the --no-ext-diff parameter to avoid it to open that tool a billion times:

git diff --no-ext-diff -p -R --no-color
| grep -E "^(diff|(old|new) mode)" --color=never
| git apply

@mariusvw
Copy link

mariusvw commented Jul 3, 2020

Seems to fail on deleted files, this resolve that

Command

git diff -p --no-ext-diff --no-color --diff-filter=d | grep -E "^(diff|old mode|new mode)" | sed -e "s/^old/NEW/;s/^new/old/;s/^NEW/new/" | git apply

Git Alias

git config --global --add alias.permission-resetb '!git diff -p --no-ext-diff --no-color --diff-filter=d | grep -E "^(diff|old mode|new mode)" | sed -e "s/^old/NEW/;s/^new/old/;s/^NEW/new/" | git apply'

@martynov-dm
Copy link

martynov-dm commented Feb 18, 2021

Seems to fail on deleted files, this resolve that

Command

git diff -p --no-ext-diff --no-color --diff-filter=d | grep -E "^(diff|old mode|new mode)" | sed -e "s/^old/NEW/;s/^new/old/;s/^NEW/new/" | git apply

Git Alias

git config --global --add alias.permission-resetb '!git diff -p --no-ext-diff --no-color --diff-filter=d | grep -E "^(diff|old mode|new mode)" | sed -e "s/^old/NEW/;s/^new/old/;s/^NEW/new/" | git apply'

Not working(

image

@neohunter
Copy link

neohunter commented Apr 11, 2021

What if it was commited and pushed? I've one commit with more than 3000 file permissions changed (mixed with real content changes). What I can do to revert the file permissions?

@neohunter
Copy link

neohunter commented Apr 11, 2021

I was able to restore permissions from a previous commit doing this:

git ls-tree -r  d3fb093 |while read mode _ _ fpath; do chmod "${mode:3}" "$fpath"; done

where d3fb093 is the last commit with the right permissions.

@BonBonSlick
Copy link

BonBonSlick commented Aug 23, 2021

tahnks! ;)

@Goddard
Copy link

Goddard commented Sep 21, 2021

Awesome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment