source

Git 복사 파일 기록 보존

ittop 2023. 6. 26. 23:11
반응형

Git 복사 파일 기록 보존

나는 Git에서 다소 혼란스러운 질문이 있습니다.예를 들어, 내가 파일을 가지고 있다고 칩시다.dir1/A.txt and 합니다.

는 그 파일을 파합니다야복사해로 .dir2/A.txt(움직이지 않고 복사).나는 그것이 있다는 것을 알고 있습니다.git mv 명령이 합니다.dir2/A.txt▁as▁▁history와 같은 dir1/A.txt,그리고.dir1/A.txt여전히 거기에 남아 있습니다.

업이트할없다습니이획계 업데이트를 할 계획이 .A.txt일단 복사본이 생성되고 모든 향후 작업이 수행될 것입니다.dir2/A.txt

혼란스럽게 들리겠지만, 이 상황이 Java 기반 모듈(Mavenized Project)에 있으며 고객이 런타임에 두 가지 다른 버전을 사용할 수 있도록 코드의 새 버전을 만들어야 합니다. 정렬이 완료되면 첫 번째 버전은 제거됩니다.우리는 물론 메이븐 버전을 사용할 수 있습니다. 저는 Git의 초보자일 뿐이며 Git이 여기서 무엇을 제공할 수 있는지 궁금합니다.

당신이 해야 할 일은 다음과 같습니다.

  1. 파일을 두 개의 다른 위치로 이동합니다.
  2. 위와 같은 두 커밋을 병합합니다.
  3. 복사본 하나를 원래 위치로 다시 이동합니다.

은 역사적을 볼 수 입니다.git blame및)git log두에 해당합니다 두 파일 모두에 적용됩니다.

.foo라고 하는bar다음과 .

git mv foo bar
git commit

SAVED=`git rev-parse HEAD`
git reset --hard HEAD^
git mv foo copy
git commit

git merge $SAVED     # This will generate conflicts
git commit -a        # Trivially resolved like this

git mv copy foo
git commit

작동하는 이유

위의 명령을 실행한 후 다음과 같은 수정 내역이 표시됩니다.

( revision history )            ( files )

    ORIG_HEAD                      foo
     /     \                      /   \
SAVED       ALTERNATE          bar     copy
     \     /                      \   /
      MERGED                     bar,copy
        |                           |
     RESTORED                    bar,foo

당신이 Git에게 Git의 역사를 물어볼 때.foo다음과 같습니다.

  1. 에서 이름 copyRESTOVEN , 합과복사이병원,이,
  2. …을 copy, Merged라는 이름의 Merged입니다.
  3. 에서 이름 fooORIG_HEAD는 ALTERNACT입니다.

거기서부터 그것은 역사를 파헤칠 것입니다.foo.

당신이 Git에게 Git의 역사를 물어볼 때.bar다음과 같습니다.

  1. MARGEED와 RESTORENED 사이에는 변경 사항이 없습니다.
  2. …을 bar MARGED의 부모로부터 .
  3. 에서 이름 fooORIG_HEAD 사 SAVE 이와.

거기서부터 그것은 역사를 파헤칠 것입니다.foo.

그렇게 간단하다.:)

추적 가능한 두 개의 파일 복사본을 허용할 수 있는 병합 상황에 Git을 강제로 적용하면 원본을 병렬로 이동하여 이 작업을 수행할 수 있습니다(곧 되돌립니다).

하위 버전과 달리 Git에는 파일별 기록이 없습니다.커밋 데이터 구조를 보면 이전 커밋과 이 커밋에 대한 새 트리 개체만 가리킵니다.커밋에 의해 변경되는 파일에 대한 명시적인 정보는 커밋 개체에 저장되지 않으며 이러한 변경 사항의 특성도 저장되지 않습니다.

변경 사항을 검사하는 도구는 휴리스틱을 기반으로 이름 변경을 탐지할 수 있습니다.예.git diff선택권이 있습니다.-M이름 바꾸기 탐지가 활성화됩니다.그래서 이름을 바꾼다면,git diff하나의 파일이 삭제되고 다른 파일이 생성되었음을 표시할 수 있습니다.git diff -M실제로 이동을 감지하고 그에 따라 변경 내용을 표시합니다( 참조).man git diff자세한 내용은).

따라서 이는 변경사항을 커밋하는 방법이 아니라 나중에 커밋된 변경사항을 어떻게 보느냐의 문제입니다.

파일을 복사하고 추가한 후 커밋하기만 하면 됩니다.

cp dir1/A.txt dir2/A.txt
git add dir2/A.txt
git commit -m "Duplicated file from dir1/ to dir2/"

그런 다음 다음 명령은 전체 사전 복사 기록을 표시합니다.

git log --follow dir2/A.txt

원본 파일에서 상속된 줄별 주석을 보려면 다음을 사용합니다.

git blame -C -C -C dir2/A.txt

Git는 커밋 시간에 복사본을 추적하지 않고 대신 기록을 검사할 때 탐지합니다.git blame그리고.git log.

이 정보의 대부분은 Git를 사용하여 파일 복사 작업을 기록합니다.

여기서 피터의 답변을 약간 수정하여 재사용 가능하고 상호 작용하지 않는 셸 스크립트를 만들었습니다.git-split.sh:

#!/bin/sh

if [[ $# -ne 2 ]] ; then
  echo "Usage: git-split.sh original copy"
  exit 0
fi

git mv "$1" "$2"
git commit -n -m "Split history $1 to $2 - rename file to target-name"
REV=`git rev-parse HEAD`
git reset --hard HEAD^
git mv "$1" temp
git commit -n -m "Split history $1 to $2 - rename source-file to temp"
git merge $REV
git commit -a -n -m "Split history $1 to $2 - resolve conflict and keep both files"
git mv temp "$1"
git commit -n -m "Split history $1 to $2 - restore name of source-file"

완벽하게 하기 위해 제어 및 제어되지 않는 파일로 가득 찬 전체 디렉터리를 복사하려면 다음을 사용할 수 있습니다.

git mv old new
git checkout HEAD old

제어되지 않은 파일은 복사되므로 다음과 같이 정리해야 합니다.

git clean -fdx new

이 경우 하드 드라이브를 변경하고(작업 복사본의 한 경로에서 다른 경로로 약 200개의 폴더/파일을 잘라내기/붙여넣기) 소스 트리(2.0.20.1)를 사용하여 탐지된 변경 사항을 모두 스테이징(한 번 추가, 한 번 제거)하고 추가 및 제거를 함께 스테이징하는 한,핑크 R 아이콘(이름 변경)으로 자동으로 단일 변경으로 결합됩니다.

한 번에 너무 많은 변경 사항이 있었기 때문에 SourceTree가 모든 변경 사항을 감지하는 속도가 약간 느려서 준비된 파일 중 일부는 단순히 추가(녹색 더하기) 또는 삭제(빨간색 빼기)하는 것처럼 보이지만, 파일 상태를 계속 새로 고치고 몇 분 후에 새로운 변경 사항이 나타날 때마다 계속 준비했습니다.모든 목록은 완벽했고 커밋할 준비가 되었습니다.

기록을 찾을 때 "이름 변경된 파일 따라하기" 옵션을 선택하면 기록이 있는지 확인합니다.

이 프로세스는 기록을 보존하지만 해결 방법이 거의 없습니다.

# make branchs to new files
$: git mv arquivos && git commit

# in original branch, remove original files
$: git rm arquivos && git commit

# do merge and fix conflicts
$: git merge branch-copia-arquivos

# back to original branch and revert commit removing files
$: git revert commit

언급URL : https://stackoverflow.com/questions/16937359/git-copy-file-preserving-history

반응형