특정 파일에 대한 변경 사항만 선택하는 방법은 무엇입니까?
Git 브랜치에 병합하려면 여러 파일에 대한 변경을 포함하여 특정 커밋에서 변경된 일부 파일에만 변경된 내용을 병합하려면 어떻게 해야 합니까?
Git ▁g▁called라고 불리는 커밋을 .stuff
되었습니다.A
,B
,C
,그리고.D
하지만 나는 오직 합병을 원합니다.stuff
에 대한 변경 사항 의 경항A
그리고.B
이를 위한 일처럼 들립니다.git cherry-pick
그렇지만cherry-pick
파일의 하위 집합이 아니라 전체 커밋을 병합하는 방법만 알고 있습니다.
는 cherry-pick -n
(--no-commit
다음을 커밋하기 전에 결과를 검사(및 수정)할 수 있습니다.
git cherry-pick -n <commit>
# unstage modifications you don't want to keep, and remove the
# modifications from the work tree as well.
# this does work recursively!
git checkout HEAD <path>
# commit; the message will have been stored for you by cherry-pick
git commit
대부분의 수정 사항이 원하지 않는 사항인 경우(중간 단계) 개별 경로를 확인하는 대신 모든 것을 다시 재설정한 다음 원하는 항목을 추가할 수 있습니다.
# unstage everything
git reset HEAD
# stage the modifications you do want
git add <path>
# make the work tree match the index
# (do this from the top level of the repo)
git checkout .
다른 많은 파일에 대한 커밋의 변경 사항과 충돌이 많았기 때문에 다른 방법은 저에게 효과가 없었습니다.제가 생각해낸 것은 단순히
git show SHA -- file1.txt file2.txt | git apply -
사실은 그렇지 않습니다.add
하거나 커밋을 해야 할 .
git add file1.txt file2.txt
git commit -c SHA
는 또추가건다사수있용다습니할음을면려너는뛰를▁the▁다▁use있니▁you를 사용할 수 있습니다.--cached
에 대한 인수입니다.git apply
git show SHA -- file1.txt file2.txt | git apply --cached -
전체 디렉토리에 대해 동일한 작업을 수행할 수도 있습니다.
git show SHA -- dir1 dir2 | git apply -
저는 주로 다음을 사용합니다.-p
다른 지점의 깃 체크아웃으로 플래그를 표시합니다. 제가 발견한 다른 대부분의 방법보다 쉽고 세분화되어 있습니다.
원칙적으로:
git checkout <other_branch_name> <files/to/grab in/list/separated/by/spaces> -p
예:
git checkout mybranch config/important.yml app/models/important.rb -p
"는 모든 하며 신호를 보낼 수 . 이는 신호를 보낼 수 있는 모든 연속적인 코드 변경에 상당한 영향을 미칩니다.y
예)(예)n
각 코드 청크에 대한 (아니오) 등.
그-p
또는patch
▁in를 포함한 다양한 에 대해 합니다.git stash save -p
할 수 .
는 이 을 제가 더 을 할 때 합니다. 저 가 제 끔 가 많 일 은 하 하 사 이 다 기 니 합 용 때 을 술 싶 을 고 커 는 을 밋 기 반 한 주 많 제 더 분 은 에 리 하 고 것 그 을 고 을 ▁using ▁in ▁commits ▁based ▁i ▁i ▁when ▁topic ▁technique ▁this 저 ▁would 다 는 ▁more ▁andgit add -p
각커밋에 을 선택합니다 :) 리고각커대에해 내원것선 다합니택 :)
상황:
당신은 당신의 지점에 있습니다.master
그리고 당신은 다른 지점에 대한 당신의 약속을 가지고 있습니다.특정 커밋에서 파일을 하나만 선택해야 합니다.
접근 방식:
1단계: 필요한 지점에서 체크아웃합니다.
git checkout master
2단계: 필요한 커밋 해시를 복사했는지 확인합니다.
git checkout commit_hash path\to\file
3단계: 이제 원하는 분기에서 필요한 파일을 변경할 수 있습니다.추가하고 커밋하기만 하면 됩니다.
git add path\to\file
git commit -m "Your commit message"
아마도 제프로미의 대답에 비해 이 방법의 장점은 깃 리셋의 어떤 행동이 옳은 행동인지 기억할 필요가 없다는 것입니다 :)
# Create a branch to throw away, on which we'll do the cherry-pick:
git checkout -b to-discard
# Do the cherry-pick:
git cherry-pick stuff
# Switch back to the branch you were previously on:
git checkout -
# Update the working tree and the index with the versions of A and B
# from the to-discard branch:
git checkout to-discard -- A B
# Commit those changes:
git commit -m "Cherry-picked changes to A and B from [stuff]"
# Delete the temporary branch:
git branch -D to-discard
체리 픽은 특정 "커밋"에서 변경 사항을 선택하는 것입니다.가장 간단한 해결책은 특정 파일의 모든 변경 사항을 선택하는 것입니다.
git checkout source_branch <paths>...
예:
$ git branch
* master
twitter_integration
$ git checkout twitter_integration app/models/avatar.rb db/migrate/20090223104419_create_avatars.rb test/unit/models/avatar_test.rb test/functional/models/avatar_test.rb
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: app/models/avatar.rb
# new file: db/migrate/20090223104419_create_avatars.rb
# new file: test/functional/models/avatar_test.rb
# new file: test/unit/models/avatar_test.rb
#
$ git commit -m "'Merge' avatar code from 'twitter_integration' branch"
[master]: created 4d3e37b: "'Merge' avatar code from 'twitter_integration' branch"
4 files changed, 72 insertions(+), 0 deletions(-)
create mode 100644 app/models/avatar.rb
create mode 100644 db/migrate/20090223104419_create_avatars.rb
create mode 100644 test/functional/models/avatar_test.rb
create mode 100644 test/unit/models/avatar_test.rb
출처 및 자세한 설명 http://jasonrudolph.com/blog/2009/02/25/git-tip-how-to-merge-specific-files-from-another-branch/
업데이트:
이 방법을 사용하면 git는 파일을 병합하지 않고 대상 분기에서 수행된 다른 변경 사항을 재정의합니다.변경 사항을 수동으로 병합해야 합니다.
gitdiff HEAD 파일 이름
완벽함을 위해 저에게 가장 적합한 것은 다음과 같습니다.
git show YOURHASH --no-color -- file1.txt file2.txt dir3 dir4 | git apply -3 --index -
OP가 원하는 것을 정확히 수행합니다.필요할 때 충돌 해결을 수행합니다. 유사한 방법으로merge
해주세요.그래요.add
하지만 아닙니다.commit
변경 은 새변사십시오참조하을을 하십시오.status
.
저는 그냥 모든 것을 고르고 나서 이렇게 할 것입니다.
git reset --soft HEAD^
그런 다음 원하지 않는 변경 사항을 되돌린 다음 새로 커밋합니다.
때로는 체크아웃을 사용하여 커밋에서 특정 파일을 가져오는 것이 더 쉬울 수 있습니다.제 생각에 그것은 당신에게 더 많은 통제력을 제공하고 체리픽 후에 확인하고 정지할 필요는 없습니다.
저는 다음과 같이 할 것입니다.
git checkout <branch|hash> -- path/to/file1 path/to/filen
그런 다음 코드를 적용하기 위해 필요한 변경 사항을 단계를 해제하고 커밋하기 전에 코드를 테스트합니다.모든 것이 예상대로 작동하면 커밋합니다.
사용하다git merge --squash branch_name
이렇게 하면 다른 분기에서 모든 변경 사항을 가져오고 사용자를 위한 커밋을 준비합니다.이제 불필요한 변경사항은 모두 제거하고 원하는 변경사항은 그대로 둡니다.그리고 git는 합병이 있었다는 것을 알지 못할 것입니다.
저는 IMO가 기억하고 이해하기 쉬운 체리 따기에서 충돌하는 합병을 방지하는 다른 방법을 찾았습니다.실제로 커밋을 선택하는 것이 아니라 일부를 선택하는 것이기 때문에 먼저 커밋을 분할한 다음 필요에 맞는 커밋을 생성하고 커밋을 선택해야 합니다.
먼저 분할할 커밋에서 분기를 만들고 체크아웃합니다.
$ git checkout COMMIT-TO-SPLIT-SHA -b temp
그런 다음 이전 커밋을 되돌립니다.
$ git reset HEAD~1
그런 다음 선택할 파일/변경사항을 추가합니다.
$ git add FILE
그리고 그것을 실행합니다.
$ git commit -m "pick me"
커밋 해시를 기록합니다. 이 해시를 PICK-SHA라고 부르고 메인 지점으로 돌아가 보겠습니다. 마스터는 체크아웃을 강제하는 예를 들어 다음과 같습니다.
$ git checkout -f master
그리고 체리 픽 커밋:
$ git cherry-pick PICK-SHA
이제 temp 분기를 삭제할 수 있습니다.
$ git branch -d temp -f
사용할 수 있는 항목:
git diff <commit>^ <commit> -- <path> | git apply
표기법<commit>^
의 (첫 번째) 부모를 지정합니다.<commit>
따라서 이 diff 명령어는 변경 사항을 선택합니다.<path>
위원회에서.<commit>
.
이것은 아직 아무것도 범하지 않을 것입니다.git cherry-pick
그래서 당신이 원한다면, 당신은 다음을 해야 할 것입니다.
git add <path>
git commit
분기를 새 분기로 병합(스쿼시)하고 필요 없는 파일을 제거합니다.
git checkout master
git checkout -b <branch>
git merge --squash <source-branch-with-many-commits>
git reset HEAD <not-needed-file-1>
git checkout -- <not-needed-file-1>
git reset HEAD <not-needed-file-2>
git checkout -- <not-needed-file-2>
git commit
조금 더 자동화하기:
#!/usr/bin/env bash
filter_commit_to_files() {
FILES="$1"
SHA="$2"
git show "$SHA" -- $FILES | git apply --index -
git commit -c "$SHA"
}
사용 예:
filter_commit_to_files "file1.txt file2.txt" 07271c5e
여기서 복사해서 제 셸에 붙여넣기를 통해 정의합니다.여기에 문서가 필요하지 않습니다.
패치 플래그를 사용한 체크아웃
당신이 설명하고 있는 것을 달성하는 쉬운 방법은 체크아웃-패치를 통해서입니다.상단에 제가 제공한 4개의 변수를 수정합니다.이 스크립트는 다음 작업을 수행합니다.
- 커밋이 포함된 분기(소스 분기)를 복제합니다.
- 파일을 이동할 지점(대상 지점)을 체크아웃합니다.
- 원하는 커밋 리비전에서 소스 분기를 체크아웃하고, 파일에 대한 패치 플래그와 상대 위치를 매개 변수로 제공합니다.
- 추가, 커밋, 푸시
이것은 항상 저에게 가장 쉬운 방법이었습니다.그러나 3단계에서는 대화형 셸을 생성하지만 대상을 클로버하려면 전체 옵션을 기본값으로 선택할 수 있습니다.
source_branch=branch_with_file_you_want
destination_branch=file_go_here
rev=757c47d4
relative_file_path=structures/serializers/node.py
message="Patching a file from $source_branch to $destination_branch"
git clone https://github.com/yourepo/app.git -b $source_branch $source_branch
cd $source_branch
git checkout $destination_branch
git checkout $rev --patch $source_branch $relative_file_path
git add $relative_file_path
git commit -m "$message"
git push
원격 사용자인 경우 GitLab을 사용할 수 있습니다.
git push -o merge_request.create
MR이 필요하시면
언급URL : https://stackoverflow.com/questions/5717026/how-to-git-cherry-pick-only-changes-to-certain-files
'programing' 카테고리의 다른 글
서로 다른 값 유형 간의 0으로 나누기 동작 불일치 (0) | 2023.05.21 |
---|---|
Mongoose: 유효성 검사 오류 경로가 필요합니다. (0) | 2023.05.21 |
OSX 10.7 Lion으로 업그레이드한 후 Postgresql 복구 (0) | 2023.05.21 |
Node.js 프로젝트의 폴더 구조 (0) | 2023.05.21 |
셸 if 문에서 여러 조건을 나타내는 방법은 무엇입니까? (0) | 2023.05.21 |