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

This comment has been minimized.

Copy link

@Dzenly 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

This comment has been minimized.

Copy link

@hadaytullah hadaytullah commented Jun 17, 2019

Thanks! appreciate the help.

@abilogos

This comment has been minimized.

Copy link

@abilogos 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

This comment has been minimized.

Copy link

@RaphiStein 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

This comment has been minimized.

Copy link

@bene20 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

This comment has been minimized.

Copy link

@mariusvw 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

This comment has been minimized.

Copy link

@martynov-dm 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

This comment has been minimized.

Copy link

@neohunter 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

This comment has been minimized.

Copy link

@neohunter 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

This comment has been minimized.

Copy link

@BonBonSlick BonBonSlick commented Aug 23, 2021

tahnks! ;)

@Goddard

This comment has been minimized.

Copy link

@Goddard Goddard commented Sep 21, 2021

Awesome!

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