programing

체크아웃을 사용하지 않고 Git 브랜치 병합, 업데이트 및 풀

topblog 2023. 4. 13. 20:28
반응형

체크아웃을 사용하지 않고 Git 브랜치 병합, 업데이트 및 풀

저는 A와 B의 2개의 지사를 가진 프로젝트를 하고 있습니다.저는 보통 A지점에서 일하며 B지점에서 물건을 병합합니다.병합을 위해 일반적으로 다음을 수행합니다.

git merge origin/branchB

다만, 지점 B의 로컬 카피도 보관하고 싶다고 생각하고 있기 때문에, 지점 A와 먼저 합병하지 않고 지점을 체크아웃 할 수도 있습니다.이를 위해 저는 다음과 같이 합니다.

git checkout branchB
git pull
git checkout branchA

브랜치를 앞뒤로 바꾸지 않고 위의 명령어를 한 번에 실행할 수 있는 방법이 있습니까?git update-ref 위해서 어떻게요?

단답

Fast-Forward Merge를 하는 한, 간단하게 사용할 수 있습니다.

git fetch <remote> <sourceBranch>:<destinationBranch>

예:

# Merge local branch foo into local branch master,
# without having to checkout master first.
# Here `.` means to use the local repository as the "remote":
git fetch . foo:master

# Merge remote branch origin/foo into local branch foo,
# without having to checkout foo first:
git fetch origin foo:foo

Amber의 답변은 빨리 감기 사례에서도 유효하지만,git fetch 것이 분기 참조를 무리하게 더 합니다.git fetch 、 will will will 、 will will will will will will will will will will will will will will will will will will will will will will will will will will will will will will will를 사용하지 한 할 수 있습니다.+참조 사양에 기재되어 있습니다.

장황한 답변

지점 B를 지점 A에 병합하려면 먼저 A를 체크하지 않으면 지점 B를 지점 A에 병합할 수 없습니다.이는 잠재적인 충돌을 해결하기 위해 작업 복사본이 필요하기 때문입니다.

단, 고속 전달 병합의 경우 이러한 병합은 정의상 충돌을 일으킬 수 없기 때문에 가능합니다.먼저 지점을 체크 아웃하지 않고 이 작업을 수행하려면git fetchrefspec으로 합니다.

업데이트의 master 전송 변경 허용) 다른 브런치( feature크크: :

git fetch upstream master:master

이 use-case는 매우 일반적이기 때문에 git 설정 파일에서 다음과 같은 에일리어스를 만들고 싶을 것입니다.

[alias]
    sync = !sh -c 'git checkout --quiet HEAD; git fetch upstream master:master; git checkout --quiet -'

이 에일리어스의 기능은 다음과 같습니다.

  1. git checkout HEAD 상태가 작업 복사본이 분리 헤드 상태가 됩니다.할때합니다.master, 「」의 브랜치 레퍼런스가 필요했기 에, 「」 레퍼런스가 합니다. 왜냐하면 그렇지 않으면 지점 참조가master움직이진 않겠지만, 그게 정말 즉석에서 한 말인지는 기억나지 않아요.

  2. git fetch upstream master:master: 로컬로 빠르게 변환됩니다.master upstream/master.

  3. git checkout - 체크 브랜치를 체크 합니다(바로 이 브랜치입니다.-을 참조해 주세요.

의 . " " "git fetch) merges(non-)의

「 」를 fetch 포워드가 아닌 를 발행합니다.이 명령어는 "fast-forward" 형식의합니다.재스펙

git fetch <remote> <remoteBranch>:<localBranch>

이외의 갱신을 허가하는 는, 「」를 합니다.+'이것'은 다음과 같습니다.

git fetch <remote> +<remoteBranch>:<localBranch>

는 remote를 사용하여 "remote"할 수 ..:

git fetch . <sourceBranch>:<destinationBranch>

문서

구문을 설명하는 문서(강조사항)에서 다음 항목을 참조하십시오.

<refspec>

<refspec> 플러스입니다.+ ref source ref에 source ref source ref가 이어집니다.<src>이 붙습니다.: ref, admination ref, admination ref, admination ref가 나옵니다.<dst>.

일치하는 remote ref가 Import되고 빈 문자열이 아닌 경우 일치하는 local ref는 를 사용하여 고속 포워딩됩니다.옵션인 plus의 경우+를 사용하면 로컬 참조는 고속 전송 업데이트가 되지 않더라도 업데이트됩니다.

참고 항목

  1. 작업 트리를 건드리지 않고 Git 체크아웃 및 병합

  2. 작업 디렉토리를 변경하지 않고 병합

아니, 없어.컨플릭트를 해결하려면 대상 브랜치의 체크 아웃이 필요합니다(Git이 자동으로 Marge할 수 없는 경우).

다만, 머지가 고속으로 전송되는 경우는, 실제로는 아무것도 머지 할 필요가 없기 때문에, 타겟 브랜치를 체크할 필요는 없습니다.브런치를 갱신해 새로운 헤드 레퍼런스를 지정하기만 하면 됩니다., 하다, 하다, 하다, 이렇게 할 수 요.git branch -f:

git branch -f branch-b branch-a

★★★★★★★★★★★★★★를 갱신합니다.branch-bbranch-a.

-f은 option을 .--force즉,branch-b덮어쓰게 됩니다.

주의:보다 안전한 옵션은 빨리 감기만 허용하는 입니다.

이 방법은 다음과 같이 사용할 수 있습니다.

git branch -f branch-b branch-b@{Upstream}

또는 더 짧음

git branch -f branch-b branch-b@{U}

체크 아웃하지 않고 분기를 강제로 갱신하려면(기본 재배치 후 분기했는지 여부)

Amber가 말한 것처럼 고속 전송 머지는 생각할 수 있는 유일한 경우입니다.다른 모든 머지에서는 패치 적용, 경합 해소 등 3방향 머지 전체를 거쳐야 합니다.즉, 주위에 파일이 존재해야 합니다.

작업 트리에 손을 대지 않고 빨리 감기 병합을 수행하는 스크립트를 사용하고 있습니다(HEAD에 병합하지 않는 한).하지 않고 수 있습니다.서 본 것처럼요.마치 머지가 고속으로 전송되는 것을 확인하고 브랜치를 체크하지 않고 실행하지만, 같은 결과를 얻을 수 있습니다.diff --stat는 "fast forward merge"를 하는 경우 "fast forward merge"를 사용하는 " forward merge"가 " forward merge"를 사용하는 경우 "fast forward merge"로 동일합니다.branch -f을 붙이면git-merge-ff디렉토리에 라고 할 수 .bin 디 、 bin 디 、 and 、 git 。git merge-ff.

#!/bin/bash

_usage() {
    echo "Usage: git merge-ff <branch> <committish-to-merge>" 1>&2
    exit 1
}

_merge_ff() {
    branch="$1"
    commit="$2"

    branch_orig_hash="$(git show-ref -s --verify refs/heads/$branch 2> /dev/null)"
    if [ $? -ne 0 ]; then
        echo "Error: unknown branch $branch" 1>&2
        _usage
    fi

    commit_orig_hash="$(git rev-parse --verify $commit 2> /dev/null)"
    if [ $? -ne 0 ]; then
        echo "Error: unknown revision $commit" 1>&2
        _usage
    fi

    if [ "$(git symbolic-ref HEAD)" = "refs/heads/$branch" ]; then
        git merge $quiet --ff-only "$commit"
    else
        if [ "$(git merge-base $branch_orig_hash $commit_orig_hash)" != "$branch_orig_hash" ]; then
            echo "Error: merging $commit into $branch would not be a fast-forward" 1>&2
            exit 1
        fi
        echo "Updating ${branch_orig_hash:0:7}..${commit_orig_hash:0:7}"
        if git update-ref -m "merge $commit: Fast forward" "refs/heads/$branch" "$commit_orig_hash" "$branch_orig_hash"; then
            if [ -z $quiet ]; then
                echo "Fast forward"
                git diff --stat "$branch@{1}" "$branch"
            fi
        else
            echo "Error: fast forward using update-ref failed" 1>&2
        fi
    fi
}

while getopts "q" opt; do
    case $opt in
        q ) quiet="-q";;
        * ) ;;
    esac
done
shift $((OPTIND-1))

case $# in
    2 ) _merge_ff "$1" "$2";;
    * ) _usage
esac

P.S. 이 스크립트에 문제가 있는 사람이 있으면 코멘트를 주세요!쓰고 잊어버리는 일이었지만, 기꺼이 개선하겠습니다.

이 작업은 머지가 패스트포워드일 경우에만 실행할 수 있습니다.그렇지 않으면 git은 파일을 체크 아웃해야 합니다.그래서 파일을 Marge 할 수 있어요!

빨리 감기 전용으로 하려면:

git fetch <branch that would be pulled for branchB>
git update-ref -m "merge <commit>: Fast forward" refs/heads/<branch> <commit>

서 ''는<commit>는 취득된 커밋으로, 고속 전송처의 커밋입니다.으로는 using것음음음음음음음음음음음음음을 사용하는 것과 같습니다.git branch -f브런치를 이동하려면 , 실제로 머지를 실행한 것처럼 리프로그에 기록합니다.

제발, 제발 빨리 전달하지 않는 것에 대해 이 일을 하지 마세요.그렇지 않으면 브랜치를 다른 커밋으로 리셋하게 됩니다.(확인하려면 ,git merge-base <branch> <commit>의 SHA1을

고객님의 경우

git fetch origin branchB:branchB

원하는 기능을 수행합니다(마지가 패스트포워드인 경우는 제외).비고속 전달 병합이 필요하기 때문에 지점을 업데이트할 수 없는 경우 메시지와 함께 안전하게 실패합니다.

이 형식의 fetch에는 다음과 같은 유용한 옵션도 있습니다.

git fetch <remote> <sourceBranch>:<destinationBranch>

:<remote> 로컬 저장소가 될 수 있습니다.<sourceBranch>추적 브랜치일 수 있습니다.따라서 네트워크에 액세스하지 않고도 체크아웃되지 않은 로컬 지점을 업데이트할 수 있습니다.

VPN접속하고 있습니다.git fetch모든 리모트를 업데이트하고 연결을 끊습니다. 리모트 는 할 수 .

git fetch . remotes/origin/master:master

현재 다른 지점을 체크 아웃하고 있는 경우에도 안전하게 최신 마스터를 갱신할 수 있습니다.네트워크 액세스는 필요 없습니다.

브랜치를 재작성하는 방법도 있습니다.

git fetch remote
git branch -f localbranch remote/remotebranch

그러면 오래된 로컬 브랜치가 폐기되고 같은 이름의 브랜치가 다시 생성되므로 주의하여 사용하십시오.

repo를 복제하고 새 repo에서 병합을 수행할 수 있습니다.같은 파일 시스템에서 대부분의 데이터를 복사하지 않고 하드링크합니다.결과를 원래 레포에 끌어다 놓고 마무리합니다.

많은 GitFlow 사용자에게 가장 유용한 명령어는 다음과 같습니다.

git fetch origin master:master --update-head-ok
git fetch origin dev:dev --update-head-ok

--update-head-ok하면 flag에서 할 수 .dev ★★★★★★★★★★★★★★★★★」master나뭇가지.

한 입니다..gitconfig:

[alias]
    f=!git fetch origin master:master --update-head-ok && git fetch origin dev:dev --update-head-ok

중에 , 왜 체크 을 해야 합니까?branchB할할면면면면면면면면?.branchBbranchA

난 원래 네가 이 일을 하기 위해서 하는 줄 알았어 origin/branchB 할 수 git fetch그래서 이 답변은 정말 이것을 바탕으로 하고 있습니다. 는 없다branchB할 수 .origin에서 origin/branchB.

B 의 는, 「B」의 으로부터 태그나 할 수 .origin/branchB.

꼭 요.origin/branchB:

git fetch
git merge origin/branchB

에는 '다 하다'를 .branchB:

git checkout branchB
git pull

이 시점에서 업데이트된 로컬 복사본을 받게 됩니다.체크 아웃을 하지 않고 실행하는 방법도 있습니다만, 이것은 거의 도움이 되지 않고, 경우에 따라서는 안전하지 않을 수도 있습니다.이를 다루는 기존 답변이 있습니다.

자세한 답변:

git pullfetch+merge하다두 , 즉 2번 비슷해요.<remote>origin는 (''), ''로합니다.<remote>/리모트 브랜치명 다음에 이어집니다.

git fetch [<remote>]
git merge @{u}

@{u}현재 분기별 원격 추적 지점을 위한 구성된 원격 추적 지점입니다.표기법은 현재 브랜치에 설정되어 있는 리모트트래킹브런치입니다 If 한다면branchB tracks 트랙origin/branchB then 그리고나서@{u}부에서branchB is the same as typing 타이핑과 동일합니다.origin/branchB (see (을 참조).git rev-parse --help세한것 、 을을해해요요 。

이미 머지하고 있기 때문에origin/branchB 「」, 「」뿐입니다.git fetch(임의의 브랜치로부터 실행할 수 있습니다).

, 로컬에 는 " " " 입니다.branchB를 Marge로 것이 좋습니다.branchBbranchAbranchB을 ( ( )으로 ).orign/branchB아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아)

해 주세요.branchB이 브랜치로 전환하여 실제 풀링을 수행할 때까지 업데이트되지 않습니다.단, 이 브랜치에 로컬 커밋이 추가되지 않는 한 리모트브런치로의 패스트포워드인 채로 있습니다.

git-forward-merge를 입력합니다.

아웃할 필요가 .git-forward-merge <source> <destination>는, 브랜치에 합니다.

https://github.com/schuyler1d/git-forward-merge

자동 병합에서만 작동하며, 충돌이 있는 경우 일반 병합을 사용해야 합니다.

대부분의 경우(마지 등) 로컬 추적 브랜치를 갱신하지 않고 리모트브런치를 사용할 수 있습니다.리플로그에 메시지를 추가하는 것은 과잉으로 들리므로 더 이상 빠르게 처리되지 않습니다.복구를 쉽게 하기 위해 git 설정에 다음 항목을 추가합니다.

[core]
    logallrefupdates=true

그런 다음 입력합니다.

git reflog show mybranch

지점의 최근 이력을 확인합니다.

프로젝트에서 매일 접하는 유사한 사용 사례에 대한 셸 함수를 작성했습니다.이는 기본적으로 PR 오픈 전 개발 등 공통 브랜치로 로컬 브랜치를 최신 상태로 유지하는 지름길입니다.

하지 이 을 올린다.checkout다른 사람들이 그 제약에 개의치 않을 경우를 대비해서요

glmh ("pull and merge here")는 자동으로checkout branchB,pull 최신판, 최신판, 최신판checkout branchA , , , , 입니다.merge branchB.

지점 A의 로컬 복사본을 유지할 필요성은 해결하지 않지만 지점 B를 체크아웃하기 전에 단계를 추가하여 쉽게 수정할 수 있습니다.뭐랄까...

git branch ${branchA}-no-branchB ${branchA}

단순 고속 전송 머지의 경우 커밋메시지 프롬프트로 건너뜁니다.

비고속 Marge의 경우 브랜치가 충돌 해결 상태(개입이 필요할 수 있음)가 됩니다.

, 「」에 추가합니다..bashrc ★★★★★★★★★★★★★★★★★」.zshrc 개요:

glmh() {
    branchB=$1
    [ $# -eq 0 ] && { branchB="develop" }
    branchA="$(git branch | grep '*' | sed 's/* //g')"
    git checkout ${branchB} && git pull
    git checkout ${branchA} && git merge ${branchB} 
}

사용방법:

# No argument given, will assume "develop"
> glmh

# Pass an argument to pull and merge a specific branch
> glmh your-other-branch

주의: 이것은 브랜치 이름을 넘어 arg를 핸드오프할 정도로 견고하지 않습니다.git merge

이를 효과적으로 수행하기 위한 또 다른 방법은 다음과 같습니다.

git fetch
git branch -d branchB
git branch -t branchB origin/branchB

-d데이터가 아직 어딘가에 존재하는 경우에만 삭제됩니다.강요하지 않는다는 점만 빼면 @koehne의 대답과 비슷합니다.그유 the the because because 。-t츠키다

OP에서 새로운 입니다.OP op op op 、develop (오류)master」를 참조해 주세요.은 강제될 수 , 않습니다.develop새로운 하고 그 기반으로 뿐입니다.origin/develop:

git checkout -b new-feature origin/develop
git worktree add [-f] [--detach] [--checkout] [--lock] [-b <new-branch>] <path> [<commit-ish>]

2개의 지점을 나란히 열어 볼 수 있습니다.원하는 것처럼 들리지만, 여기서 본 다른 답변과는 크게 다릅니다.

이와 같이 동일한 git repo에 2개의 다른 브랜치를 트래킹할 수 있기 때문에 두 개의 워크 트리에서 업데이트를 받기 위해 한 번만 가져오면 됩니다(클론을 두 번 복제하고 각각을 풀링할 필요가 없습니다).

Worktree는 코드를 위한 새로운 작업 디렉토리를 만듭니다.이 디렉토리에서 브런치를 교환하는 대신 다른 브런치를 동시에 체크아웃할 수 있습니다.

제거할 때 다음을 사용하여 청소할 수 있습니다.

git worktree remove [-f] <worktree>

내가 사용하는 마스터를 확인하지 않고 마스터를 끌어당기기 위해서

git fetch origin master:master

머지라도)를 수.git checkout . 。worktree좋은 힌트입니다. @http go 하려면:자세한 내용은 다음과 같습니다.

cd local_repo
git worktree add _master_wt master
cd _master_wt
git pull origin master:master
git merge --no-ff -m "merging workbranch" my_work_branch
cd ..
git worktree remove _master_wt

으로 로컬 워크브런치로 되었습니다.master분기를 변경할 수 있습니다.

병합할 브랜치 중 하나와 동일한 트리를 유지하는 경우(즉,'진짜'가 아니라 이렇게 하면 돼요.

# Check if you can fast-forward
if git merge-base --is-ancestor a b; then
    git update-ref refs/heads/a refs/heads/b
    exit
fi

# Else, create a "merge" commit
commit="$(git commit-tree -p a -p b -m "merge b into a" "$(git show -s --pretty=format:%T b)")"
# And update the branch to point to that commit
git update-ref refs/heads/a "$commit"

이것은 실제로 일상 업무 흐름에서 매우 중요한 기능입니다.참고용으로 여기에 문서화해야 합니다.

를 들어, 내가 예 a a에서 가정해 보자.feat1입니다만, 제가 할 .feat2이것은 현재보다 훨씬 뒤의 분기입니다.HEAD는 이 번째 체크 아웃입니다.feat2 , 을합니다.git rebase feat그러나 이 경우 보통 실행 중인 개발 서버가 변경을 검출하여 이전 버전으로 재렌더합니다.이러한 변경은 작업 트리가 현재 브랜치와 너무 다르면 크래시됩니다. 위해 브런치에 feat1는 그냥 git fetch <repo> <src>:<dst>위의 경우 다음과 같습니다.

git fetch . HEAD:feat2

또는

git fetch . feat1:feat2

후 ★★★feat2 as as will will as 。와 .feat1하게 체크 아웃 할 수 feat2개발 서버를 손상시키지 않고 사용할 수 있습니다.

말하면 .git pull origin branchB의 에 your에branchA【 git 】【git】

언급URL : https://stackoverflow.com/questions/3216360/merge-update-and-pull-git-branches-without-using-checkouts

반응형