![이 예에서 ` patch -p1`은 어떤 파일에 패치를 적용합니까?](https://rvso.com/image/109227/%EC%9D%B4%20%EC%98%88%EC%97%90%EC%84%9C%20%60%20patch%20-p1%60%EC%9D%80%20%EC%96%B4%EB%96%A4%20%ED%8C%8C%EC%9D%BC%EC%97%90%20%ED%8C%A8%EC%B9%98%EB%A5%BC%20%EC%A0%81%EC%9A%A9%ED%95%A9%EB%8B%88%EA%B9%8C%3F.png)
커밋에서 파일 변경 사항을 되돌리려면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
) 파일의 컨텍스트를 패치와 비교합니다. 컨텍스트가 일치하는 경우에만(퍼즈 옵션에 따라 몇 줄 이내) 변경 사항이 적용됩니다.
이 스크립트의 요점은 주어진 커밋(따라서 이름)에서 단일 파일에 대한 변경 사항을 되돌리려는 것입니다. 이것이 가능한지 여부는 해당 커밋 이후 파일에 적용된 변경 사항에 따라 다릅니다. 하지만 실제로는 꽤 유용할 때가 많습니다. (전체 커밋을 되돌리려면 대신 사용하세요 git revert
.)