커밋에서 파일 변경 사항을 되돌리려면 다음으로 시작하세요.https://stackoverflow.com/a/2620822/156458
#!/bin/bash
function output_help {
echo "usage: git-revert-single-file <sha1> <file>"
}
sha1=$1
file=$2
if [[ $sha1 ]]; then
git diff $sha1..$sha1^ -- $file | patch -p1
else
output_help
fi
패치 파일은 어떤 파일에 적용됩니까 patch -p1
(예: 출력 git diff $sha1..$sha1^ -- $file
)?
작업 디렉토리의 모든 파일에 적용됩니까?
그러나 작업 디렉터리는 커밋 디렉터리와 다를 수 있습니다 $sha1
. 그렇다면 와 동일할 수도 있고 아닐 수도 있는 작업 디렉토리에 $sha1^
와 의 차이점을 적용하는 것이 의미가 있습니까 ?$sha1
$sha1
감사해요.
답변1
git diff $sha1..$sha1^
커밋을 되돌리는 패치를 생성합니다 $sha1
(해당 커밋과 상위 커밋 간의 차이점을 나열합니다). 지정된 경우 해당 커밋에서 변경된 내용 $file
으로 패치가 제한됩니다 .$file
그런 다음 해당 패치를 에 제공하면 사용된 가짜 디렉토리 이름이 제거되고 patch -p1
패치에 나열된 모든 파일에 패치를 적용하려고 시도합니다(git
a/
b/
즉, $file
지정된 커밋에서 이름이 지정되고 변경된 경우 또는 하위 디렉터리의 파일을 포함하여 지정된 커밋에서 모든 파일이 변경된 경우). 현재 디렉터리와 하위 디렉터리에 있는 파일이 크게 다른 경우(또는 확장자가 누락된 경우) patch
패치가 적용되지 않습니다.
git diff
이는 ( 및 diff -u
)에 의해 생성된 균일한 형식의 패치에 패치되는 파일 이름과 패치 컨텍스트가 포함되어 있다는 사실에 의해 달성됩니다 . 다음은 예입니다( 의 내용은 아니지만 git
아이디어를 보여줍니다).
diff -ur cli-common-0.9+nmu1.orig/policy-remove cli-common-0.9+nmu1/policy-remove
--- cli-common-0.9+nmu1.orig/policy-remove 2015-02-25 21:34:08.000000000 +0100
+++ cli-common-0.9+nmu1/policy-remove 2017-04-08 20:47:09.029065259 +0200
@@ -11,4 +11,4 @@
#echo "Removing GAC policy file ($POLICY) from available GACs"
/usr/share/cli-common/gac-package-remove $POLICY > /dev/null
-rm /usr/share/cli-common/packages.d/$POLICY.installcligac
+rm -f /usr/share/cli-common/packages.d/$POLICY.installcligac
패치는 이라는 cli-common-0.9+nmu1.orig/policy-remove
파일을 생성하기 위해 이라는 파일을 수정하고 있다고 말합니다 cli-common-0.9+nmu1/policy-remove
. 변경 자체는 11번째 줄에서 시작하여 @@ -11,4
대상의 컨텍스트(예: )를 포함하여 4개 줄에 걸쳐 있으며 변경된 줄은 동일한 위치( +11,4 @@
)에 있습니다. 변경 사항 위에는 세 줄의 컨텍스트가 있고 그 다음에는 변경 사항 자체가 있습니다. 로 시작하는 줄을 제거 rm
하고 로 시작하는 줄을 추가합니다 rm -f
. 이 기능이 적용되면 patch
적절한 이름의 파일을 찾고(옵션으로 표시된 경우 경로 구성 요소를 제거한 후 -p
) 컨텍스트가 일치하는 경우에만(몇 줄 내에서) 파일의 컨텍스트를 패치와 비교합니다. fuzz 옵션)은 변경 사항을 적용합니다.
이 스크립트의 전체 목적은 특정 커밋(따라서 이름)에서 단일 파일에 대한 변경 사항을 되돌리려는 것입니다. 이것이 가능한지 여부는 파일이 커밋된 이후 변경된 내용에 따라 다르지만 실제로는 매우 유용합니다. (완전한 커밋을 복원하려면 이 방법을 사용할 수 있습니다 git revert
.)