etc./StackOverFlow

Git의 다른 분기에서 변경 사항을 선택적으로 병합하거나 선택하려면 어떻게 해야 합니까?

청렴결백한 만능 재주꾼 2022. 2. 15. 08:48
반응형

질문자 :David Joyner


두 개의 병렬(그러나 현재 실험적인) 개발 분기가 있는 새 프로젝트에서 Git을 사용하고 있습니다.

  • master : 기존 코드베이스 가져오기 및 일반적으로 확신하는 몇 가지 수정 사항
  • exp1 : 실험 분기 #1
  • exp2 : 실험 분기 #2

exp1exp2 는 매우 다른 두 가지 아키텍처 접근 방식을 나타냅니다. 내가 더 나아질 때까지 나는 어떤 것이 (둘 중 하나라도) 효과가 있을지 알 방법이 없습니다. 한 브랜치에서 진행하면서 다른 브랜치에서 유용할 수 있는 편집 내용이 있고 그 부분만 병합하고 싶은 경우가 있습니다.

한 개발 분기에서 다른 개발 분기로 선택적 변경 사항을 병합하면서 다른 모든 것은 남겨두는 가장 좋은 방법은 무엇입니까?

내가 고려한 접근 방식 :

  1. git merge --no-commit 다음에 브랜치 간에 공통으로 만들고 싶지 않은 많은 수의 편집을 수동으로 언스테이징합니다.

  2. 일반 파일을 임시 디렉토리로 수동 복사한 다음 git checkout 을 사용하여 다른 분기로 이동한 다음 임시 디렉토리에서 작업 트리로 수동 복사합니다.

  3. 위의 변형입니다. exp 브랜치를 포기하고 실험을 위해 두 개의 추가 로컬 리포지토리를 사용합니다. 이것은 파일의 수동 복사를 훨씬 더 간단하게 만듭니다.

이 세 가지 접근 방식 모두 지루하고 오류가 발생하기 쉽습니다. 더 나은 접근 방식이 있기를 바랍니다. git-merge 보다 선택적으로 만드는 필터 경로 매개변수와 유사한 것입니다.



나는 위에서 당신이 언급 한 것과 똑같은 문제가있었습니다. 그러나 나는 대답을 설명하면서 이것을 더 명확하게 발견했습니다.

요약:

  • 병합하려는 분기의 경로를 확인하고,

     $ git checkout source_branch -- <paths>... Hint: It also works without `--` like seen in the linked post.
  • 또는 덩어리를 선택적으로 병합하려면

     $ git checkout -p source_branch -- <paths>...

또는 reset을 사용한 다음 -p 옵션으로 추가하십시오.

 $ git reset <paths>... $ git add -p <paths>...
  • 마지막으로 커밋

     $ git commit -m "'Merge' these changes"

Community Wiki

한 분기에서 개별 커밋을 가져오려면 cherry-pick 명령을 사용합니다.

원하는 변경 사항이 개별 커밋에 없는 경우 여기에 표시된 방법을 사용 하여 커밋을 개별 커밋으로 분할합니다 . 대략적으로 말하면 git rebase -i 를 사용하여 편집할 원본 커밋을 가져온 다음 git reset HEAD^ 를 사용하여 변경 사항을 선택적으로 되돌린 다음 git commit 을 사용하여 해당 비트를 기록에 새 커밋으로 커밋합니다.

여기 Red Hat Magazine에는 git add --patch 또는 git add --interactive 를 사용하는 또 다른 좋은 방법이 있습니다. 이 방법 을 사용하면 개별 파일에 다른 변경 사항을 분할하려는 경우 덩어리의 일부만 추가할 수 있습니다(검색 "분할"에 대한 해당 페이지에서).

변경 사항을 분할하면 이제 원하는 항목만 선택할 수 있습니다.


1800 INFORMATION

한 분기의 파일을 다른 분기로 선택적으로 병합하려면 다음을 실행하십시오.

 git merge --no-ff --no-commit branchX

여기서 branchX 는 현재 분기로 병합하려는 분기입니다.

--no-commit 옵션은 Git에 의해 병합된 파일을 실제로 커밋하지 않고 스테이징합니다. 이렇게 하면 병합된 파일을 원하는 대로 수정한 다음 직접 커밋할 수 있습니다.

파일 병합 방법에 따라 다음 네 가지 경우가 있습니다.

1) 진정한 병합을 원합니다.

이 경우 Git이 자동으로 병합하는 방식으로 병합된 파일을 수락한 다음 커밋합니다.

2) 병합하고 싶지 않은 파일이 있습니다.

예를 들어 현재 분기의 버전을 유지하고 병합하려는 분기의 버전을 무시하려고 합니다.

현재 분기에서 버전을 선택하려면 다음을 실행하십시오.

 git checkout HEAD file1

이것은 현재 분기에서 file1 의 버전을 검색하고 Git에 의해 자동 병합된 file1

3) branchX의 버전을 원할 경우(진정한 병합이 아닌).

운영:

 git checkout branchX file1

branchX 에서 file1 의 버전을 검색하고 Git에 의해 자동 병합된 file1 덮어씁니다.

file1 에서 특정 병합만 선택하려는 경우입니다.

이 경우, 수정 편집 할 수 있습니다 file1 당신의 버전 싶어 무엇으로 업데이트, 직접 file1 되고, 다음 커밋합니다.

Git이 파일을 자동으로 병합할 수 없는 경우 파일을 " 병합 되지 않음 "으로 보고하고 충돌을 수동으로 해결해야 하는 복사본을 생성합니다.



예를 들어 더 자세히 설명하기 위해 branchX 를 현재 분기에 병합하려고 한다고 가정해 보겠습니다.

 git merge --no-ff --no-commit branchX

그런 다음 git status 명령을 실행하여 수정된 파일의 상태를 봅니다.

예를 들어:

 git status # On branch master # Changes to be committed: # # modified: file1 # modified: file2 # modified: file3 # Unmerged paths: # (use "git add/rm <file>..." as appropriate to mark resolution) # # both modified: file4 #

여기서 file1 , file2file3 은 git이 성공적으로 자동 병합된 파일입니다.

이것이 의미하는 바는 masterbranchX 변경 사항이 충돌 없이 함께 결합되었다는 것입니다.

git diff --cached 실행하여 병합이 어떻게 수행되었는지 검사할 수 있습니다.

 git diff --cached file1 git diff --cached file2 git diff --cached file3

일부 병합이 바람직하지 않은 경우 다음을 수행할 수 있습니다.

  1. 파일을 직접 편집
  2. 저장
  3. git commit

file1 을 병합하지 않고 현재 분기의 버전을 유지하려는 경우

운영

 git checkout HEAD file1

file2 를 병합하고 싶지 않고 branchX 의 버전만 원하는 경우

운영

 git checkout branchX file2

file3 를 자동으로 병합하려면 아무 것도 하지 마십시오.

Git은 이 시점에서 이미 병합했습니다.


file4 는 Git에서 실패한 병합입니다. 이는 동일한 라인에서 발생하는 두 가지 모두에 변경 사항이 있음을 의미합니다. 여기에서 충돌을 수동으로 해결해야 합니다. file4 가 되기를 원하는 분기의 버전에 대한 체크아웃 명령을 실행하여 병합된 작업을 취소할 수 있습니다.


마지막으로 git commit 잊지 마십시오.


alvinabad

나는 위의 접근 방식을 좋아하지 않습니다. 체리픽을 사용하는 것은 단일 변경 사항을 선택하는 데는 좋지만 일부 잘못된 변경 사항을 제외하고 모든 변경 사항을 가져오려는 경우에는 골치 아픈 일입니다. 여기 내 접근 방식이 있습니다.

git merge에 전달할 수 있는 --interactive 인수가 없습니다.

대안은 다음과 같습니다.

분기 '기능'에 일부 변경 사항이 있고 일부를 '마스터'로 가져오고 싶지는 않지만 조잡하지 않은 방식으로(즉, 체리 선택 및 커밋하고 싶지 않음)

 git checkout feature git checkout -b temp git rebase -i master # Above will drop you in an editor and pick the changes you want ala: pick 7266df7 First change pick 1b3f7df Another change pick 5bbf56f Last change # Rebase b44c147..5bbf56f onto b44c147 # # Commands: # pick = use commit # edit = use commit, but stop for amending # squash = use commit, but meld into previous commit # # If you remove a line here THAT COMMIT WILL BE LOST. # However, if you remove everything, the rebase will be aborted. # git checkout master git pull . temp git branch -d temp

따라서 이를 쉘 스크립트로 래핑하고 master를 $to로 변경하고 기능을 $from으로 변경하면 됩니다.

 #!/bin/bash # git-interactive-merge from=$1 to=$2 git checkout $from git checkout -b ${from}_tmp git rebase -i $to # Above will drop you in an editor and pick the changes you want git checkout $to git pull . ${from}_tmp git branch -d ${from}_tmp

nosatalian

다른 방법이 있습니다.

 git checkout -p

git checkoutgit add -p 혼합한 것이며 당신이 찾고 있는 것과 정확히 일치할 수 있습니다.

 -p, --patch Interactively select hunks in the difference between the <tree-ish> (or the index, if unspecified) and the working tree. The chosen hunks are then applied in reverse to the working tree (and if a <tree-ish> was specified, the index). This means that you can use git checkout -p to selectively discard edits from your current working tree. See the “Interactive Mode” section of git-add(1) to learn how to operate the --patch mode.

Chronial

이러한 답변 중 일부는 꽤 좋지만 실제로 OP의 원래 제약 조건인 특정 분기에서 특정 파일을 선택하는 데 대답한 사람은 아무도 없는 것 같습니다. 이 솔루션은 그렇게 하지만 파일이 많은 경우 지루할 수 있습니다.

master , exp1exp2 분기가 있다고 가정해 보겠습니다. 각 실험 분기에서 하나의 파일을 마스터로 병합하려고 합니다. 나는 다음과 같이 할 것입니다 :

 git checkout master git checkout exp1 path/to/file_a git checkout exp2 path/to/file_b # Save these files as a stash git stash # Merge stash with master git merge stash

이렇게 하면 원하는 각 파일에 대한 파일 내 diff가 제공됩니다. 더 이상 아무것도 없습니다. 그 이하도 아닙니다. 버전 간에 근본적으로 다른 파일 변경 사항이 있는 것이 유용합니다. 제 경우에는 애플리케이션을 Ruby on Rails 2에서 Ruby on Rails 3으로 변경하는 것입니다.

이것은 파일을 병합하지만 스마트 병합을 수행합니다. 파일 내 diff 정보를 얻기 위해 이 방법을 사용하는 방법을 알 수 없었습니다(극단적인 차이에 대해서는 여전히 그럴 것입니다. -s recursive -X ignore-all-space 옵션)


Eric Hu

1800 INFORMATION의 대답 은 완전히 정확합니다. 그러나 Git을 처음 사용하는 사람으로서 "git cherry-pick 사용"은 인터넷에서 조금 더 파고들지 않고는 이것을 알아내기에 충분하지 않았기 때문에 다른 사람이 비슷한 배에서.

내 사용 사례는 다른 사람의 GitHub 분기에서 내 자신의 분기로 변경 사항을 선택적으로 가져오기를 원했습니다. 변경 사항이 포함된 로컬 분기가 이미 있는 경우 2단계와 5-7단계만 수행하면 됩니다.

  1. 가져오려는 변경 사항으로 로컬 브랜치를 생성합니다(생성되지 않은 경우).

    $ git branch mybranch <base branch>

  2. 그것으로 전환하십시오.

    $ git checkout mybranch

  3. 다른 사람의 계정에서 원하는 변경 사항을 끌어내립니다. 아직 추가하지 않았다면 리모컨으로 추가하고 싶을 것입니다.

    $ git remote add repos-w-changes <git url>

  4. 그들의 가지에서 모든 것을 끌어내십시오.

    $ git pull repos-w-changes branch-i-want

  5. 커밋 로그를 보고 원하는 변경 사항을 확인하세요.

    $ git log

  6. 변경 사항을 가져올 분기로 다시 전환하십시오.

    $ git checkout originalbranch

  7. 체리는 해시를 사용하여 커밋을 하나씩 선택합니다.

    $ git cherry-pick -x hash-of-commit


Cory

다음은 master 브랜치의 Myclass.java 파일을 feature1 브랜치의 Myclass.java master Myclass.java 가 존재하지 않는 경우에도 작동합니다.

 git checkout master git checkout feature1 Myclass.java

이것은 병합이 아니라 덮어쓰고 대신 마스터 분기의 로컬 변경 사항을 무시합니다.


maestr0

단순히 특정 파일을 다른 분기의 파일로 바꾸는 것이 아니라 두 분기의 특정 파일 을 실제로 병합 하는 간단한 방법입니다.

1단계: 가지 구별하기

git diff branch_b > my_patch_file.patch

현재 브랜치와 branch_b의 차이점에 대한 패치 파일을 생성합니다.

2단계: 패턴과 일치하는 파일에 패치 적용

git apply -p1 --include=pattern/matching/the/path/to/file/or/folder my_patch_file.patch

옵션에 대한 유용한 참고 사항

* 를 와일드카드로 사용할 수 있습니다.

슬래시는 이스케이프할 필요가 없습니다.

또한 대신 --exclude를 사용하고 패턴과 일치하는 파일을 제외한 모든 것에 적용하거나 -R로 패치를 반전할 수 있습니다.

-p1 옵션은 *Unix 패치 명령의 홀드오버이며 패치 파일의 내용이 각 파일 이름 앞에 제거해야 a/ 또는 b/ (또는 패치 파일 생성 방식에 따라 더 많이)를 추가한다는 사실입니다. 패치를 적용해야 하는 파일의 경로에 대한 실제 파일을 파악할 수 있습니다.

더 많은 옵션은 git-apply 매뉴얼 페이지를 확인하십시오.

3단계: 3단계는 없습니다

분명히 변경 사항을 커밋하고 싶지만 커밋하기 전에 수행하고 싶은 다른 관련 조정이 없다고 말할 수 있습니다.


masukomi

더 "간단한" 병합이 원하지 않는 변경 사항을 훨씬 더 많이 가져왔을지라도 최소한의 소란으로 다른 브랜치에서 몇 개의 파일만 추적하도록 히스토리를 얻을 수 있는 방법은 다음과 같습니다.

먼저 Git이 작업 디렉토리에 있는 파일에 대해 아무 작업도 수행하지 않고 커밋하려는 항목이 병합임을 미리 선언하는 비정상적인 단계를 수행합니다.

 git merge --no-ff --no-commit -s ours branchname1

... 여기서 "branchname"은 병합 대상이라고 주장하는 모든 것입니다. 즉시 커밋하면 변경 사항이 없지만 여전히 다른 분기의 조상을 표시합니다. 필요한 경우 명령줄에 더 많은 분기, 태그 등을 추가할 수도 있습니다. 이 시점에서 커밋할 변경 사항이 없으므로 다음에 다른 개정판에서 파일을 가져옵니다.

 git checkout branchname1 -- file1 file2 etc.

둘 이상의 다른 분기에서 병합하는 경우 필요에 따라 반복합니다.

 git checkout branchname2 -- file3 file4 etc.

이제 다른 분기의 파일이 히스토리와 함께 커밋될 준비가 된 인덱스에 있습니다.

 git commit

그리고 그 커밋 메시지에서 해야 할 많은 설명이 있을 것입니다.

그러나 명확하지 않은 경우를 대비하여 이것이 엉망이라는 점에 유의하십시오. 그것은 "가지"가 무엇을 위한 것인지에 대한 정신이 아니며 여기서 체리 선택은 당신이 하려는 일을 하는 보다 정직한 방법입니다. 이전에 가져오지 않은 동일한 분기의 다른 파일에 대해 다른 "병합"을 수행하려는 경우 "이미 최신 상태"라는 메시지가 표시되면서 중지됩니다. "from" 분기가 하나 이상의 다른 분기여야 한다는 점에서 분기하지 않는 증상입니다.


Community Wiki

가장 쉬운 방법은 저장소를 병합하려는 분기로 설정한 다음 실행하는 것입니다.

 git checkout [branch with file] [path to file you would like to merge]

실행하면

 git status

이미 준비된 파일이 표시됩니다...

그런 다음 실행

 git commit -m "Merge changes on '[branch]' to [file]"

단순한.


dsieczko

이것은 선택 파일을 병합하기 위한 내 워크플로입니다.

 # Make a new branch (this will be temporary) git checkout -b newbranch # Grab the changes git merge --no-commit featurebranch # Unstage those changes git reset HEAD (You can now see the files from the merge are unstaged) # Now you can chose which files are to be merged. git add -p # Remember to "git add" any new files you wish to keep git commit

Felix

이 게시물 에 가장 간단한 답변이 포함되어 있음을 알았습니다. 다음을 수행하기만 하면 됩니다.

 git checkout <branch from which you want files> <file paths>

예시

.gitignore 파일을 branchB에서 현재 분기로 가져오기:

 git checkout branchB .gitignore

자세한 내용은 게시물을 참조하세요.


Stunner

git에 "즉시 사용 가능한" 편리한 도구가 아직 없다는 것이 이상합니다. 현재 버전 분기의 일부 버그 수정으로 일부 이전 버전 분기(여전히 많은 소프트웨어 사용자가 있음)를 업데이트할 때 많이 사용합니다. 이 경우 트렁크에 있는 파일에서 몇 줄의 코드만 빠르게 가져와야 하고 다른 많은 변경 사항은 무시해야 합니다(이전 버전에는 적용되지 않음)... 그리고 물론 대화형 3방향 병합 이 경우 필요하며 git checkout --patch <branch> <file path> 는 이 선택적 병합 용도로 사용할 수 없습니다.

당신은 그것을 쉽게 할 수 있습니다:

.gitconfig 또는 로컬 .git/config 파일의 [alias] 섹션에 다음 줄을 추가하기만 하면 됩니다.

 [alias] mergetool-file = "!sh -c 'git show $1:$2 > $2.theirs; git show $(git merge-base $1 $(git rev-parse HEAD)):$2 > $2.base; /C/BCompare3/BCompare.exe $2.theirs $2 $2.base $2; rm -f $2.theirs; rm -f $2.base;' -"

Beyond Compare를 사용한다는 의미입니다. 필요한 경우 원하는 소프트웨어로 변경하기만 하면 됩니다. 또는 대화형 선택적 병합이 필요하지 않은 경우 3방향 자동 병합으로 변경할 수 있습니다.

 [alias] mergetool-file = "!sh -c 'git show $1:$2 > $2.theirs; git show $(git merge-base $1 $(git rev-parse HEAD)):$2 > $2.base; git merge-file $2 $2.base $2.theirs; rm -f $2.theirs; rm -f $2.base;' -"

그런 다음 다음과 같이 사용하십시오.

 git mergetool-file <source branch> <file path>

이것은 다른 분기에 있는 모든 파일의 진정한 선택적 트리 방식 병합 기회를 제공합니다.


JimStar

그것은 당신이 찾고 있던 것이 아니지만 나에게 유용했습니다.

 git checkout -p <branch> -- <paths> ...

몇 가지 답변이 혼합되어 있습니다.


Felipe

나는 위에서 당신이 언급 한 것과 똑같은 문제가있었습니다. 하지만 이 Git 블로그 가 답을 설명하는 데 더 명확하다는 것을 알았습니다.

위 링크의 명령:

 # You are in the branch you want to merge to git checkout <branch_you_want_to_merge_from> <file_paths...>

Susheel Javadi

나는 할 것이다

자식 diff commit1..commit2 파일 패턴 | git-apply --index && git 커밋

이렇게 하면 분기에서 파일 패턴에 대한 커밋 범위를 제한할 수 있습니다.

Re: 한 지점에서 다른 지점으로 몇 개의 파일만 가져오는 방법은 무엇입니까?


lumpidu

저에게 git reset --soft branch 는 다른 분기에서 변경 사항을 선택적으로 선택하는 가장 쉬운 방법입니다. 이 명령은 작업 트리에 모든 diff 변경 사항을 넣고 필요한 것을 쉽게 선택하거나 되돌릴 수 있기 때문입니다.

이런 식으로 커밋된 파일을 완전히 제어할 수 있습니다.


GarryOne

이전 'git-interactive-merge' 답변이 마음에 들지만 더 쉬운 방법이 있습니다. 대화형 및 on의 rebase 조합을 사용하여 Git이 이 작업을 수행하도록 합니다.

 A---C1---o---C2---o---o feature / ----o---o---o---o master

따라서 '기능' 분기(분기점 'A')에서 C1과 C2를 원하지만 나머지는 지금 당장은 원하지 않습니다.

 # git branch temp feature # git checkout master # git rebase -i --onto HEAD A temp

이전 답변에서와 같이 C1 및 C2에 대한 '선택' 행을 선택하는 대화식 편집기로 이동합니다(위 참조). 저장하고 종료하면 리베이스가 진행되고 마스터 + C1 + C2에 'temp' 분기와 HEAD가 제공됩니다.

 A---C1---o---C2---o---o feature / ----o---o---o---o-master--C1---C2 [HEAD, temp]

그런 다음 마스터를 HEAD로 업데이트하고 임시 분기를 삭제하면 됩니다.

 # git branch -f master HEAD # git branch -d temp

Wade

디렉토리를 부분적으로 병합하기 위해 'pmerge'라는 스크립트를 작성했습니다. 진행중인 작업이며 여전히 Git과 Bash 스크립팅을 모두 배우고 있습니다.

이 명령은 git merge --no-commit 을 사용한 다음 제공된 경로와 일치하지 않는 변경 사항을 적용 취소합니다.

사용법: git pmerge branch path
예: git merge develop src/

나는 그것을 광범위하게 테스트하지 않았습니다. 작업 디렉토리에는 커밋되지 않은 변경 사항과 추적되지 않은 파일이 없어야 합니다.

 #!/bin/bash E_BADARGS=65 if [ $# -ne 2 ] then echo "Usage: `basename $0` branch path" exit $E_BADARGS fi git merge $1 --no-commit IFS=$'\n' # List of changes due to merge | replace nulls with newlines | strip lines to just filenames | ensure lines are unique for f in $(git status --porcelain -z -uno | tr '\000' '\n' | sed -e 's/^[[:graph:]][[:space:]]\{1,\}//' | uniq); do [[ $f == $2* ]] && continue if git reset $f >/dev/null 2>&1; then # Reset failed... file was previously unversioned echo Deleting $f rm $f else echo Reverting $f git checkout -- $f >/dev/null 2>&1 fi done unset IFS

Andy

read-tree 를 사용하여 주어진 원격 트리를 읽거나 현재 인덱스로 병합할 수 있습니다. 예를 들면 다음과 같습니다.

 git remote add foo git@example.com/foo.git git fetch foo git read-tree --prefix=my-folder/ -u foo/master:trunk/their-folder

병합을 수행하려면 -m 사용하십시오.

참조: Git에서 하위 디렉토리를 어떻게 병합합니까?


kenorb

파일에 의한 선택적 병합/커밋을 위한 간단한 접근 방식:

 git checkout dstBranch git merge srcBranch // Make changes, including resolving conflicts to single files git add singleFile1 singleFile2 git commit -m "message specific to a few files" git reset --hard # Blow away uncommitted changes

Dave C

변경된 파일이 너무 많지 않은 경우 추가 커밋이 발생하지 않습니다.

1. 일시적으로 분기 복제
$ git checkout -b temp_branch

2. 마지막으로 원하는 커밋으로 재설정
$ git reset --hard HEAD~n , 여기서 n 은 돌아가야 하는 커밋 수입니다.

3. 원본 브랜치에서 각 파일 체크아웃
$ git checkout origin/original_branch filename.ext

이제 필요한 경우 커밋하고 강제로 푸시(원격 덮어쓰기)할 수 있습니다.


JBaczuk

특정 디렉터리만 병합하고 다른 모든 것은 그대로 두고 기록을 보존해야 하는 경우 이 작업을 시도할 수 있습니다... 실험하기 전에 master target-branch

단계는 아래 두 가지를 가정 해 target-branchsource-branch 및 디렉토리 dir-to-merge 당신이에 병합 할 것을 source-branch . 또한 히스토리를 변경하고 유지하고 싶지 않은 대상에 dir-to-retain 과 같은 다른 디렉토리가 있다고 가정합니다. dir-to-merge 에 병합 충돌이 있다고 가정합니다.

 git checkout target-branch git merge --no-ff --no-commit -X theirs source-branch # the option "-X theirs", will pick theirs when there is a conflict. # the options "--no--ff --no-commit" prevent a commit after a merge, and give you an opportunity to fix other directories you want to retain, before you commit this merge. # the above, would have messed up the other directories that you want to retain. # so you need to reset them for every directory that you want to retain. git reset HEAD dir-to-retain # verify everything and commit.

code4kix

두 분기의 현재 커밋 사이에 몇 개의 파일만 변경된 경우 다른 파일을 통해 변경 사항을 수동으로 병합합니다.

git difftool <branch-1>..<branch-2>

https://sites.google.com/site/icusite/setup/git-difftool도 참조하세요.


raratiru

저는 관심이 있었던 이 문제의 하위 집합에 집중할 것입니다. 두 개의 분기가 있고 하나의 파일 에서 다른 파일로 하나의 파일을 의사 병합하려고 합니다.

(나는 병합 커밋이 필요하지 않거나 원하지 않기 때문에 "의사 병합"이라고 말합니다. 내가 보기에 적합하다고 생각되는 방식으로 파일의 두 버전 모두의 기여를 결합하고 싶을 뿐입니다.)

내 접근 방식은 https://stackoverflow.com/a/39916536/341994 에서 취한 접근 방식을 기반으로 합니다. 불행히도 그 질문은 중복으로 닫혀 있습니다(내 생각에는 이 질문의 중복이 아니며 답변자가 거기에서 한 것처럼 중복으로 응답하고 닫기는 잘못된 것입니다). 그러나 그 대답에는 몇 가지 잘못된 점이 있으므로 접근 방식을 현대화하고 정리했습니다. checkoutreset 대신에 restore 사용하고 필요하지 않은 것은 커밋하지 않습니다.

자, 세 개의 파일이 있다고 상상해 보세요.

 $ ls abf

otherbranch a , 그 중 하나만을 의사 병합하고 싶습니다. 그들의 상황이 어떤 모습일지 지켜보자. 내 버전은 다음과 같습니다.

 $ cat a line one line two line three line four line five

otherbranch의 버전은 다음과 같습니다.

 $ git show otherbranch:a line one line two edited line three line four line five line six

이제 여기서 트릭은 인덱스를 스크래치 패드(결국 그것이 무엇을 위한 것인지)로 사용한다는 것입니다. 따라서 버전이 인덱스에 복사되었는지 확인하여 시작합니다(1단계).

 $ git add a

이제(2단계) restore otherbranch 에서 버전을 가져올 수 있습니다(요즘에는 보다 명확하게 말할 수 있으므로 restore checkout 보다 낫습니다):

 $ git restore --source otherbranch a

언뜻 보기에 이것은 나쁘게 보입니다. otherbranch 의 버전으로 완전히 덮어썼습니다.

 $ cat a line one line two edited line three line four line five line six

하지만 걱정하지 마세요! 의 이전 버전은 다음과 같이 여전히 색인에 있습니다.

 $ git diff a diff --git a/ab/a index abf51fa..333614b 100644 --- a/a +++ b/a @@ -1,6 +1,7 @@ line one -line two +line two edited line three line four line five +line six

자, 이제 키 이동을 위한 준비가 되었습니다(3단계). 작업 트리에서 인덱스로 파일 의 대화식 패치 add 를 수행합니다.

git add -pa 라고 말할 수 있습니다. 이 경우 한 번에 하나씩 덩어리가 제공됩니다. 그러나 이 경우에는 덩어리가 하나만 있고 어쨌든 편집하고 싶으므로 다음과 같이 말합니다.

 $ git add --ea

그 결과 우리는 편집기에서 diff의 패치 파일을 엽니다! 다음과 같습니다.

 line one -line two +line two edited line three line four line five +line six

신중한 편집을 통해 이제 수락할 부분과 수락하지 않을 부분을 결정할 수 있습니다. "라인 6"은 허용하지만 "라인 2 편집됨"은 허용하지 않습니다. 그래서 우리는 다음과 같이 편집합니다:

 line one line two line three line four line five +line six

편집기를 닫고 패치가 의 인덱스 버전에 적용됩니다. 그러나 우리는 완전히 끝나지 않았습니다! 의 다른 otherbranch 버전은 여전히 작업 트리에 있습니다.

 $ cat a line one line two edited line three line four line five line six

우리가 좋아하는 버전이 색인에 있습니다. 기억하시나요? 그것을 얻으려면 (4단계) git restore plain and simple을 호출합니다(다시 말하지만 이것은 현대적인 방식입니다. restore reset 보다 좋으며 단일 파일에 적용할 수 있습니다):

 $ git restore a

이제 우리는 정확하고 우리는 모두 끝났습니다.

 $ cat a line one line two line three line four line five line six

이 시점에서 커밋할 수 있지만 꼭 할 필요는 없습니다. 우리는 우리가 달성하기로 설정한 것을 달성했습니다.


matt

출처 : http:www.stackoverflow.com/questions/449541/how-can-i-selectively-merge-or-pick-changes-from-another-branch-in-git

반응형