จะคืนค่าการอนุญาตของไฟล์และไดเรกทอรีภายใน git ได้อย่างไรถ้าพวกมันถูกแก้ไข?


278

ฉันมีการชำระเงินคอมไพล์ การอนุญาตของไฟล์ทั้งหมดนั้นแตกต่างจากสิ่งที่ git คิดว่าควรเป็นเช่นนั้นพวกเขาทั้งหมดจึงแสดงว่ามีการแก้ไข

โดยไม่ต้องสัมผัสเนื้อหาของไฟล์ (แค่ต้องการแก้ไขการอนุญาต) ฉันจะตั้งค่าการอนุญาตไฟล์ทั้งหมดเป็น git ที่คิดว่าควรจะเป็นอย่างไร


คำตอบ:


572

Git ติดตาม filepermission git diff -pและตีแผ่สิทธิ์ในการเปลี่ยนแปลงเมื่อมีการสร้างแพทช์ใช้ ดังนั้นสิ่งที่เราต้องการคือ:

  1. สร้างแพทช์กลับ
  2. รวมเฉพาะการเปลี่ยนแปลงการอนุญาต
  3. ใช้แพทช์กับสำเนาการทำงานของเรา

ในฐานะที่เป็นหนึ่งซับ:

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

คุณสามารถเพิ่มเป็นนามแฝงในการตั้งค่า git ของคุณ ...

git config --global --add alias.permission-reset '!git diff -p -R --no-ext-diff --no-color | grep -E "^(diff|(old|new) mode)" --color=never | git apply'

... และคุณสามารถเรียกใช้ได้ผ่าน:

git permission-reset

หมายเหตุถ้าคุณใช้ shell bashให้ใช้'แทน"เครื่องหมายคำพูดล้อมรอบ!gitมิฉะนั้นจะถูกแทนที่ด้วยgitคำสั่งสุดท้ายที่คุณรัน

thx เพื่อ @Mixologic สำหรับการชี้ให้เห็นว่าโดยเพียงแค่ใช้-Rในgit diffการยุ่งยากsedคำสั่งไม่จำเป็น


3
ฉันอยู่ใน OS X นี่ไม่ทำงาน ฉันพบว่าปัญหาอยู่ในการใช้คอมไพล์ ไม่ใช้การเปลี่ยนแปลงการอนุญาตของไฟล์
pepper_chico

15
โอ้มันใช้งานได้ฉันพยายามสมัครจากไดเรกทอรีที่แตกต่างจากที่เก็บราก git ใช้งานได้ที่นั่นเท่านั้น
pepper_chico

6
มีเหตุผลบางอย่างที่คุณจะไม่ทำเพียงแค่ "git diff -p -R" แทนที่จะทำสิ่งที่ดีเพื่อทำให้มันกลับด้านหรือไม่?
Mixologic

6
@RobQuist การเปลี่ยนแปลงในตัวเครื่องของฉันไม่ได้ถูกลบเมื่อใช้คำสั่งของ
muhqu

17
ฉันจะได้รับfatal: unrecognized input
Tieme

120

ลอง git config core.fileMode false

จากgit configหน้าคน:

core.fileMode

หากเป็นเท็จความแตกต่างของบิตที่เรียกใช้งานได้ระหว่างดัชนีและสำเนาการทำงานจะถูกละเว้น มีประโยชน์กับระบบไฟล์ที่ใช้งานไม่ได้เช่น FAT ดูคอมไพล์ปรับปรุงดัชนี (1)

ค่าเริ่มต้นคือความจริงยกเว้น git-clone (1) หรือ git-init (1) จะสอบสวนและตั้งค่า core.fileMode false ถ้าเหมาะสมเมื่อสร้างที่เก็บข้อมูล


ขอบคุณนี่คือสิ่งที่ฉันทำ ใช้มากในการ CV ไม่ได้ติดตามการอนุญาตดังนั้นจึงใช้งานได้
Dale Forester

3
@shovas: ฉันดีใจที่ช่วยได้ ฉันประสบปัญหาคล้ายกันเมื่อแบ่งปัน repos ระหว่าง Linux และ Windows BTW: ถ้าสิ่งนี้ตอบคำถามของคุณโปรดทำเครื่องหมายการตอบว่าถูกต้อง
Tim Henigan

เป็นไปได้หรือไม่ที่git checkout origin/masterจะตั้งค่าการอนุญาตให้ไฟล์ไปยังเซิร์ฟเวอร์เป็นสำเนาการทำงานในเครื่อง เพราะเมื่อใดก็ตามที่ฉันสร้าง V8 สำหรับ ArangoDB การอนุญาตของไฟล์จะเปลี่ยนไปดังนั้นการเข้าถึงจะถูกปฏิเสธไปยังโฟลเดอร์บิลด์ทั้งหมด (แม้จะมีสิทธิ์ในการยกระดับ; ฉันต้องแก้ไขการอนุญาตไฟล์ในเครื่องทั้งหมดก่อนจึงจะสามารถดำเนินการต่อได้ สามารถcore.filemode falseแก้ไขได้หรือไม่ ฉันสงสัยว่าคอมไพล์ตั้งค่าการอนุญาต Linux บนเครื่อง Windows ของฉัน สคริปต์การสร้างอาจเก็บรักษาไว้และใช้การอนุญาตเดียวกันกับไฟล์ที่สร้างขึ้นใหม่ ...
CodeManX

อิ่มสงสัยว่าถ้ามีข้อเสียใด ๆ กับการตั้งค่าfilemodeไปfalse!
kevoroid

11

Git ไม่ได้จัดเก็บการอนุญาตไฟล์นอกเหนือจากสคริปต์ที่เรียกใช้งานได้ ลองใช้สิ่งอื่นเช่นgit-cache-metaเพื่อบันทึกความเป็นเจ้าของไฟล์และการอนุญาต

Git สามารถเก็บโหมดได้สองประเภทเท่านั้น: 755 (ปฏิบัติการ) และ 644 (ไม่ใช่ปฏิบัติการ) หากไฟล์ของคุณเป็น 444 git จะเก็บไว้เป็น 644


14
ขออภัย แต่นี่ไม่ถูกต้อง แน่นอนว่า Git จะติดตามการอนุญาต
จะ

4
มันถูกต้องประมาณดูgit.wiki.kernel.org/index.php/ContentLimitations สิทธิ์ที่แน่นอนที่ได้รับชุดปรากฏอยู่บนพื้นฐานของเซิร์ฟเวอร์และอาจจะเป็นลูกค้าumaskเช่นเดียวกับการตั้งค่าการกำหนดค่าดูstackoverflow.com/a/12735291/125150
Motti Strom

12
@ ไม่ก็ไม่ได้ ไม่สามารถเชื่อว่าความคิดเห็นของคุณมี upvotes มากมาย
eis

@ จะนี้ถูกต้องประมาณ ตามเอกสาร ...a mode of 100644, which means it’s a normal file. Other options are 100755, which means it’s an executable file; and 120000, which specifies a symbolic link. The mode is taken from normal UNIX modes but is much less flexible — these three modes are the only ones that are valid for files (blobs) in Git (although other modes are used for directories and submodules).
esmail

9
git diff -p \
| grep -E '^(diff|old mode|new mode)' \
| sed -e 's/^old/NEW/;s/^new/old/;s/^NEW/new/' \
| git apply

จะทำงานได้ในกรณีส่วนใหญ่ แต่ถ้าคุณมีเครื่องมือ diff ภายนอกเช่นติดตั้ง meld คุณต้องเพิ่ม - no-ext-diff

git diff --no-ext-diff -p \
    | grep -E '^(diff|old mode|new mode)' \
    | sed -e 's/^old/NEW/;s/^new/old/;s/^NEW/new/' \
    | git apply

เป็นสิ่งจำเป็นในสถานการณ์ของฉัน



0

ฉันใช้คอมไพล์จาก cygwin บน Windows git applyโซลูชันไม่ทำงานสำหรับฉัน นี่คือทางออกของฉันรันchmodทุกไฟล์เพื่อรีเซ็ตการอนุญาต

#!/bin/bash
IFS=$'\n'
for c in `git diff -p |sed -n '/diff --git/{N;s/diff --git//g;s/\n/ /g;s# a/.* b/##g;s/old mode //g;s/\(.*\) 100\(.*\)/chmod \2 \1/g;p}'`
do
        eval $c
done
unset IFS


-1

git diff -pใช้ในคำตอบของ muhquอาจไม่แสดงความคลาดเคลื่อนทั้งหมด

  • เห็นสิ่งนี้ใน Cygwin สำหรับไฟล์ที่ฉันไม่ได้เป็นเจ้าของ
  • การเปลี่ยนแปลงโหมดจะถูกละเว้นอย่างสมบูรณ์ถ้าcore.filemodeเป็นfalse(ซึ่งเป็นค่าเริ่มต้นสำหรับ MSysGit)

รหัสนี้อ่านเมตะดาต้าโดยตรงแทน:

(set -o errexit pipefail nounset;
git ls-tree HEAD -z | while read -r -d $'\0' mask type blob path
do
    if [ "$type" != "blob" ]; then continue; fi;
    case "$mask" in
    #do not touch other bits
    100644) chmod a-x "$path";;
    100755) chmod a+x "$path";;
    *) echo "invalid: $mask $type $blob\t$path" >&2; false;;
    esac
done)

สายการบินเดียวที่ไม่ใช่เกรดการผลิต (แทนที่หน้ากากทั้งหมด):

git ls-tree HEAD | perl -ne '/^10(0\d{3}) blob \S+\t(.+)$/ && { system "chmod",$1,$2 || die }'

(เครดิตสำหรับ "$ '\ 0'" ไปที่http://transnum.blogspot.ru/2008/11/bashs-read-built-in-supports-0-as.html )


-2

สิ่งที่ง่ายที่สุดที่จะทำคือเพียงแค่เปลี่ยนการอนุญาตกลับคืน ในฐานะที่เป็น @ kroger สังเกตว่าคอมไพล์เพียงแทร็คบิตที่ปฏิบัติการได้ ดังนั้นคุณอาจต้องเรียกใช้chmod -x filenameเพื่อแก้ไข (หรือ+xถ้านั่นคือสิ่งที่จำเป็น


นี่คือตัวอย่างจากgit show: diff --git a / OpenWatch / src / org / ale / openwatch / fb / FBUtils.java b / OpenWatch / src / org / ale / openwatch / fb / FBUtils.java ดัชนี ee5b0935 100644 นั่น ตัวหนาเล็กน้อยมีสิทธิ์ของไฟล์
Conrado

ดูเหมือนว่าฉันจะง่ายที่สุดเช่นกัน แต่น่าเสียดายที่ผมพบปัญหาเช่นเดียวกับ Conrado - ฉันไม่สามารถเปลี่ยนได้รับอนุญาตจากไป100644 100755ฉันไม่คิดว่าคุณควรได้รับ downvote; Git ควรลงคะแนน มันแตกในหลาย ๆ ระดับที่แตกต่างกัน ...
jww

-2

etckeeperเครื่องมือที่สามารถจัดการกับการอนุญาตและด้วย:

etckeeper init -d /mydir

คุณสามารถใช้มันสำหรับ dirs /etcอื่นที่ไม่ใช่

ติดตั้งโดยใช้ตัวจัดการแพ็คเกจของคุณหรือรับแหล่งข้อมูลจากลิงค์ด้านบน


4
มันตั้งค่าการอนุญาตเป็นอย่างไร หากไม่ได้อ่านข้อมูลเมตา Git หรือเรียกใช้ Git มันจะไม่ทำตามที่ OP ร้องขอ
ivan_pozdeev
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.