bestsource

"git pull --all"이 모든 로컬 분기를 업데이트할 수 있습니까?

bestsource 2023. 4. 29. 09:34
반응형

"git pull --all"이 모든 로컬 분기를 업데이트할 수 있습니까?

마스터, 스테이징, 프로덕션 등 3개 이상의 원격 지사가 있는 경우가 많습니다.저는 그 원격 지점들을 추적하는 3개의 지역 지점을 가지고 있습니다.

모든 로컬 지점을 업데이트하는 것은 지루합니다.

git fetch --all
git rebase origin/master
git checkout staging
git rebase origin/staging
git checkout production
git rebase origin/production

저는 그냥 "git pull - all"을 할 수 있기를 원하지만, 저는 그것을 작동시킬 수 없었습니다."모두 가져오기"를 수행한 다음 현재 작동 중인 분기를 업데이트(빠른 전달 또는 병합)하지만 다른 로컬 분기는 업데이트하지 않습니다.

여전히 각 로컬 지점으로 수동으로 전환하고 업데이트하는 중입니다.

허브의 하위 명령을 사용하여 이를 자동화합니다.있습니다alias git=hub내 안에서.bash_profile제가 입력하는 명령은 다음과 같습니다.

git sync

이렇게 하면 일치하는 업스트림 분기가 있는 모든 로컬 분기가 업데이트됩니다.맨 페이지에서:

  • 로컬 분기가 오래된 경우 빨리 전달합니다.
  • 로컬 분기에 푸시되지 않은 작업이 포함된 경우 경고합니다.
  • 분기가 병합된 것처럼 보이고 해당 업스트림 분기가 삭제된 경우 삭제합니다.

또한 현재 분기에서 커밋되지 않은 변경 내용을 저장/저장 해제합니다.

예전에 git-up이라는 비슷한 툴을 사용했는데, 더 이상 유지보수가 되지 않고,git sync거의 정확히 같은 일을 합니다.

사자가설 동작는하에 설명하는 pull --all꼭 유용한 것은 아니지만 정확히 예상대로입니다.fetch로 모든 를 모든.pull그런 다음 적절한 단일 분기를 병합(또는 기본 재배치)합니다.

다른 지점들도 확인해보려면 확인해보셔야 합니다.그리고 예, 병합(및 기본 재배치)에는 워크 트리가 절대적으로 필요하므로 다른 분기를 확인하지 않고는 수행할 수 없습니다.원하는 경우 설명된 단계를 스크립트/에일리어스로 마무리할 수 있습니다. 단, 다음과 같은 명령을 사용하는 것이 좋습니다.&&만약 그들 중 한 명이 실패한다면, 그것은 계속하려고 하지 않을 것입니다.

저는 이 질문이 거의 3년 전의 것이라는 것을 알고 있지만, 저는 저 자신에게 똑같은 질문을 던졌고 이미 만들어진 해결책을 찾지 못했습니다.그래서 저는 직접 사용자 지정 git 명령 셸 스크립트를 만들었습니다.

자, 시니다합작,.git-ffwd-update스크립트에서 다음 작업을 수행합니다.

  1. 발행합니다.git remote update 판본을
  2. 사합니다를 사용합니다.git remote show분기를 원격 ▁that(▁to▁branches다)▁can니)git pull)
  3. 그리고 나서 그것은 확인합니다.git rev-list --count <REMOTE_BRANCH>..<LOCAL_BRANCH>원격 뒤에 있는 로컬 분기의 커밋 수(그 반대의 경우도 앞에 있음)
  4. 로컬 분기가 1개 이상 커밋 앞에 있으면 빠르게 전달할 수 없으므로 수동으로 병합하거나 기반을 변경해야 합니다.
  5. 로컬 브랜치가 0 커밋 앞에 있고 1개 이상의 커밋 뒤에 있으면 다음을 통해 빠르게 처리할 수 있습니다.git branch -f <LOCAL_BRANCH> -t <REMOTE_BRANCH>

스크립트는 다음과 같이 호출할 수 있습니다.

$ git ffwd-update
Fetching origin
 branch bigcouch was 10 commit(s) behind of origin/bigcouch. resetting local branch to remote
 branch develop was 3 commit(s) behind of origin/develop. resetting local branch to remote
 branch master is 6 commit(s) behind and 1 commit(s) ahead of origin/master. could not be fast-forwarded

전체 스크립트는 다음과 같이 저장해야 합니다.git-ffwd-update 그고그필다니합요은것리▁the에 있어야 합니다.PATH.

#!/bin/bash

main() {
  REMOTES="$@";
  if [ -z "$REMOTES" ]; then
    REMOTES=$(git remote);
  fi
  REMOTES=$(echo "$REMOTES" | xargs -n1 echo)
  CLB=$(git rev-parse --abbrev-ref HEAD);
  echo "$REMOTES" | while read REMOTE; do
    git remote update $REMOTE
    git remote show $REMOTE -n \
    | awk '/merges with remote/{print $5" "$1}' \
    | while read RB LB; do
      ARB="refs/remotes/$REMOTE/$RB";
      ALB="refs/heads/$LB";
      NBEHIND=$(( $(git rev-list --count $ALB..$ARB 2>/dev/null) +0));
      NAHEAD=$(( $(git rev-list --count $ARB..$ALB 2>/dev/null) +0));
      if [ "$NBEHIND" -gt 0 ]; then
        if [ "$NAHEAD" -gt 0 ]; then
          echo " branch $LB is $NBEHIND commit(s) behind and $NAHEAD commit(s) ahead of $REMOTE/$RB. could not be fast-forwarded";
        elif [ "$LB" = "$CLB" ]; then
          echo " branch $LB was $NBEHIND commit(s) behind of $REMOTE/$RB. fast-forward merge";
          git merge -q $ARB;
        else
          echo " branch $LB was $NBEHIND commit(s) behind of $REMOTE/$RB. resetting local branch to remote";
          git branch -f $LB -t $ARB >/dev/null;
        fi
      fi
    done
  done
}

main $@

자동화하는 것은 그리 어렵지 않습니다.

#!/bin/sh
# Usage: fetchall.sh branch ...

set -x
git fetch --all
for branch in "$@"; do
    git checkout "$branch"      || exit 1
    git rebase "origin/$branch" || exit 1
done

이것은 여전히 자동이 아닙니다. 옵션이 있기를 바랍니다. 그리고 이것이 빨리 감기 업데이트에만 발생할 수 있는지 확인하기 위한 몇 가지 확인이 있어야 합니다. (그래서 수동으로 풀을 하는 것이 훨씬 안전합니다!!) 그러나 주의 사항은 제쳐두고 다음과 같습니다.

git fetch origin
git update-ref refs/heads/other-branch origin/other-branch

로컬 지점의 위치를 확인할 필요 없이 업데이트할 수 있습니다.

참고: 현재 분기 위치를 잃고 오리진의 분기 위치로 이동하게 됩니다. 즉, 병합이 필요한 경우 데이터가 손실됩니다.

여에는많답있사답없용다습은니는하지를 하는 답은 .git-fetch보다 훨씬 직접 합니다.git-update-ref.

서 우리는 는방하법을 합니다.git-fetch되지 않는 합니다.git pull --ff-only당지에 대하여내용:

  • 분기를 체크아웃할 필요가 없습니다.
  • 분기를 빨리 회송할 수 있는 경우에만 업데이트
  • 빨리 전달할 수 없을 때 보고합니다.

그리고 여기 있습니다.

#!/bin/bash
currentbranchref="$(git symbolic-ref HEAD 2>&-)"
git branch -r | grep -v ' -> ' | while read remotebranch
do
    # Split <remote>/<branch> into remote and branchref parts
    remote="${remotebranch%%/*}"
    branchref="refs/heads/${remotebranch#*/}"

    if [ "$branchref" == "$currentbranchref" ]
    then
        echo "Updating current branch $branchref from $remote..."
        git pull --ff-only
    else
        echo "Updating non-current ref $branchref from $remote..."
        git fetch "$remote" "$branchref:$branchref"
    fi
done

다음에 대한 관리 페이지에서git-fetch:

   <refspec>
       The format of a <refspec> parameter is an optional plus +, followed by the source ref <src>,
       followed by a colon :, followed by the destination ref <dst>.

       The remote ref that matches <src> is fetched, and if <dst> is not empty string, the local ref
       that matches it is fast-forwarded using <src>. If the optional plus + is used, the local ref is
       updated even if it does not result in a fast-forward update.

git fetch <remote> <ref>:<ref>)+ 업데이트될 수 있을 로컬 참조가 빠르게 처리될 수 있을 때만 업데이트되는 검색을 받습니다.

로컬 및 원격 지점의 이름이 동일하다고 가정하고(모든 지점을 추적하려는 경우), 사용자가 가지고 있는 로컬 지점과 해당 지점이 추적하도록 설정된 항목에 대한 정보를 실제로 사용해야 합니다.

이 문제는 (아직) 해결되지 않았습니다. 적어도 스크립트 없이는 쉽지 않습니다. Junio C Hamano가 상황을 설명하고 간단한 해결책을 제공하는 git 메일링 목록에 있는 이 게시물참조하십시오.

주요 이유는 이것이 필요하지 않아야 한다는 것입니다.

오래되지 않은 git(예: v1.5.0 이상)을 사용하면 더 이상 순수하게 리모컨을 추적하는 로컬 "dev"를 가질 이유가 없습니다.만약 당신이 가서 보고만 하고 싶다면, 당신은 "로 분리된 HEAD에서 직접 원격 추적 지점을 체크아웃할 수 있습니다.git checkout origin/dev".

즉, 사용자가 편리하게 사용할 수 있도록 해야 하는 경우는 로컬 변경사항이 있을 때 또는 로컬 변경사항이 있을 때 원격 브랜치를 "추적"하는 이러한 로컬 브랜치를 처리하는 것뿐입니다.

"로컬 이 있어 "dev되어 있고 "dev"와 경우 "dev" 에는 아무것도 수행하지 않아야 합니다git fetch원격 추적 "dev"를 업데이트합니다. 안 갈

솔루션에 대한 요구는 옵션 또는 외부 스크립트가 요청된 원래 포스터처럼 빠르게 전달하여 최신 상태로 유지하는 것이 아니라 현재 원격 추적 분기를 따르는 로컬 분기를 제거하는 것이었습니다.

그서어 "요래때 "어래서 "는 어때요?git branch --prune --remote=<upstream>지점을 되며, "" "" "" "" "" "" "" "" "" "" " " " " " " " "" 입니다.

분기가 . 그리고 .
됩니다. </FONT CHANGE:> 지서추위표다니시됩해기적하에가.
; 자체적없습니다커밋이로.

그럼 그 나뭇가지를 제거하시겠습니까?"git remote --prune-local-forks <upstream>기능을 구현하는 명령이 무엇이든 상관하지 않습니다.

참고: git 2.10 기준으로 이러한 솔루션은 존재하지 않습니다.참고:git remote prune명령 및 "는 다음과 같습니다."git fetch --prune는 더 이상 원격에 존재하지 않는 분기에 대한 원격 검색 분기를 제거하는 것에 관한 것이지 원격 검색 분기를 추적하는 로컬 분기를 제거하는 것이 아닙니다(원격 검색 분기가 업스트림 분기인 경우).

여기에는 수용 가능한 답이 많이 있지만, 일부 배관은 초보자들에게는 약간 불투명할 수 있습니다.다음은 쉽게 사용자 지정할 수 있는 훨씬 간단한 예입니다.

$ cat ~/bin/git/git-update-all
#!/bin/bash
# Update all local branches, checking out each branch in succession.
# Eventually returns to the original branch. Use "-n" for dry-run.
git_update_all() {
  local run br
  br=$(git name-rev --name-only HEAD 2>/dev/null)
  [ "$1" = "-n" ] && shift && run=echo

  for x in $( git branch | cut -c3- ) ; do
     $run git checkout $x && $run git pull --ff-only || return 2
  done

  [ ${#br} -gt 0 ] && $run git checkout "$br"
}

git_update_all "$@"

추가하는 경우~/bin/git의 신에게에.PATH이 (으)로 표시됨)~/bin/git/git-update-all), 그냥 실행할 수 있습니다.

$ git update-all

나는 이 질문과 같은 문제를 우연히 발견했습니다...

는 그것에, 제 는나그대궁해금면서하해했, 에▁my▁inside▁function▁alias▁wondering▁small다▁a했니 안에서 작은 별칭 기능을 했습니다..bashrc파일 이름:

gitPullAll() {
    for branch in `git branch | sed -E 's/^\*/ /' | awk '{print $1}'`; do
        git checkout $branch
        git pull -p
        printf "\n"
    done
    echo "Done"
}

나를 위해 일함(:

다음은 좋은 대답입니다.모든 깃 분기를 가져오는 방법

for remote in `git branch -r`; do git branch --track $remote; done
git pull --all

다음에 이 스크립트 추가.profileX의 경우: Mac OS X우:

# Usage:
#   `git-pull-all` to pull all your local branches from origin
#   `git-pull-all remote` to pull all your local branches from a named remote

function git-pull-all() {
    START=$(git symbolic-ref --short -q HEAD);
    for branch in $(git branch | sed 's/^.//'); do
        git checkout $branch;
        git pull ${1:-origin} $branch || break;
    done;
    git checkout $START;
};

function git-push-all() {
    git push --all ${1:-origin};
};

하나의 git 명령으로는 할 수 없고 하나의 bash 줄로 자동화할 수 있습니다.

모든 분기를 한 줄로 안전하게 업데이트하려면 다음 작업을 수행합니다.

git fetch --all && for branch in $(git branch | sed '/*/{$q;h;d};$G' | tr -d '*') ; do git checkout $branch && git merge --ff-only || break ; done
  • 분기 하나를 빨리 전달할 수 없거나 오류가 발생하면 해당 분기가 중지되고 사용자가 해당 분기에 남아 수동으로 제어 권한을 되찾고 병합할 수 있습니다.

  • 모든 분기를 빨리 회송할 수 있는 경우, 현재 있던 분기로 끝납니다. 업데이트하기 전의 위치는 그대로 유지됩니다.

설명:

가독성을 향상시키기 위해 여러 줄로 분할할 수 있습니다.

git fetch --all && \
for branch in $(git branch | sed '/*/{$q;h;d};$G' | tr -d '*')
    do git checkout $branch && \
    git merge --ff-only || break
done
  1. git fetch --all && ...=> 모든 원격에서 모든 ref를 가져오고 오류가 없으면 다음 명령을 계속합니다.

  2. git branch | sed '/*/{$q;h;d};$G' | tr -d '*'=> =>의git branch,sed을 서다, 을 서다, 줄을 *현재 분기가 마지막으로 업데이트되도록 끝까지 이동합니다.그리고나서tr 간히제를 합니다.*.

  3. for branch in $(...) ; do git checkout $branch && git merge --ff-only || break ; done> 이전 명령에서 얻은 각 분기 이름에 대해 이 분기를 체크아웃하고 빠른 전달과 병합을 시도합니다.한다면, 하면실패.break이 호출되고 명령은 여기서 중지됩니다.

물론, 당신은 대체할 수 있습니다.git merge --ff-only와 함께git rebase당신이 원하는 것이라면.

마지막으로 bashrc에 별칭으로 저장할 수 있습니다.

alias git-pull-all='git fetch --all && for branch in $(git branch | sed '\''/*/{$q;h;d};$G'\'' | tr -d "*") ; do git checkout $branch && git merge --ff-only || break ; done'

또는 '와 '를 혼동하는 것이 두렵거나 단순히 편집기에서 구문적 가독성을 유지하는 것을 선호하는 경우, 이를 함수로 선언할 수 있습니다.

git-pull-all()
{
    git fetch --all && for branch in $(git branch | sed '/*/{$q;h;d};$G' | tr -d '*') ; do git checkout $branch && git merge --ff-only || break ; done
}

보너스:

위의 설명을 원하는 사람들을 위해.sed '/*/{$q;h;d};$G'표시된 항목:

  • /*/=> => 라인을 합니다.*.

  • {$q=> 마지막 줄에 있으면 종료합니다(현재 지점이 이미 목록의 마지막 지점이기 때문에 아무것도 할 필요가 없습니다)

  • ;h;d}=> 그렇지 않으면 Hold 버퍼에 라인을 저장한 후 현재 목록 위치에서 삭제합니다.

  • ;$G=> 마지막 줄에 도달하면 홀드 버퍼의 내용을 추가합니다.

GitBash를 위해 쓴 대본.다음을 수행합니다.

  • 기본적으로 원점을 추적하도록 설정된 모든 분기에 대해 원점에서 풀합니다. 원하는 경우 다른 원격을 지정할 수 있습니다.
  • 현재 분기가 더티 상태인 경우 변경 내용을 스테이징하고 마지막에 이러한 변경 내용을 복원하려고 시도합니다.
  • 원격 분기를 추적하도록 설정된 각 로컬 분기에 대해 다음 작업을 수행합니다.
    • git checkout branch
    • git pull origin
  • 마지막으로 원래 분기 및 복원 상태로 돌아갑니다.

저는 이것을 사용하지만 철저하게 테스트하지 않았습니다. 위험을 감수하고 사용하세요.여기에서 .bash_alias 파일의 이 스크립트 예제를 참조하십시오.

    # Do a pull on all branches that are tracking a remote branches, will from origin by default.
    # If current branch is dirty, will stash changes and reply after pull.
    # Usage: pullall [remoteName]
    alias pullall=pullAll
    function pullAll (){
     # if -h then show help
     if [[ $1 == '-h' ]]
    then
      echo "Description: Pulls new changes from upstream on all branches that are tracking remotes."
      echo 
      echo "Usage: "
      echo "- Default: pullall"
      echo "- Specify upstream to pull from: pullall [upstreamName]"
      echo "- Help: pull-all -h"
    else

     # default remote to origin
     remote="origin"
     if [ $1 != "" ]
     then
       remote=$1
     fi

     # list all branches that are tracking remote
     # git branch -vv : list branches with their upstreams
     # grep origin : keep only items that have upstream of origin
     # sed "s/^.."... : remove leading *
     # sed "s/^"..... : remove leading white spaces
     # cut -d" "..... : cut on spaces, take first item
     # cut -d splits on space, -f1 grabs first item
     branches=($(git branch -vv | grep $remote | sed "s/^[ *]*//" | sed "s/^[ /t]*//" | cut -d" " -f1))

     # get starting branch name
     startingBranch=$(git rev-parse --abbrev-ref HEAD)

     # get starting stash size
     startingStashSize=$(git stash list | wc -l)

     echo "Saving starting branch state: $startingBranch"
     git stash

     # get the new stash size
     newStashSize=$(git stash list | wc -l)

     # for each branch in the array of remote tracking branches
     for branch in ${branches[*]}
     do
       echo "Switching to $branch"
       git checkout $branch

       echo "Pulling $remote"
       git pull $remote

     done

     echo "Switching back to $startingBranch"
     git checkout $startingBranch

     # compare before and after stash size to see if anything was stashed
     if [ "$startingStashSize" -lt "$newStashSize" ]
     then
       echo "Restoring branch state"
       git stash pop
     fi
    fi
    }

Windows(윈도우)에 있는 경우 의 복제품인 PyGitUp을 사용할 수 있습니다.git-up파이썬용.Pip을 사용하여 설치할 수 있습니다.pip install --user git-up또는 를 사용하여 Spoop을 통해scoop install git-up

[4]

업스트림 분기와 이름이 일치하는 분기만 빠르게 전달하는 약간 다른 스크립트입니다.또한 빠른 회송이 가능한 경우 현재 분기를 업데이트합니다.

합니다.git branch -vv를 다을사업분설정으로 합니다.git branch -u origin/yourbanchname

파일 및 chmod 755에 복사 붙여넣기:

#!/bin/sh

curbranch=$(git rev-parse --abbrev-ref HEAD)

for branch in $(git for-each-ref refs/heads --format="%(refname:short)"); do
        upbranch=$(git config --get branch.$branch.merge | sed 's:refs/heads/::');
        if [ "$branch" = "$upbranch" ]; then
                if [ "$branch" = "$curbranch" ]; then
                        echo Fast forwarding current branch $curbranch
                        git merge --ff-only origin/$upbranch
                else
                        echo Fast forwarding $branch with origin/$upbranch
                        git fetch . origin/$upbranch:$branch
                fi
        fi
done;

업데이트된 답변을 게시하는 중입니다. git-up는 더 이상 유지 관리되지 않으며 설명서를 읽으면 이제 git에서 이 기능을 사용할 수 있다고 합니다.

Git 2.9를 기준으로 Git pull --rebase --autostash는 기본적으로 같은 일을 합니다.

따라서 Git 2.9 이상으로 업데이트하는 경우 Git-up을 설치하는 대신 다음 별칭을 사용할 수 있습니다.

git config --global alias.up 'pull --rebase --autostash'

다시간대수있습도다니정설에 이 값을 할 수 .git pullGit 2.9 기준으로도 마찬가지입니다(고마워요 @VonC 여기서 그의 답변을 보세요).

git config --global pull.rebase true
git config --global rebase.autoStash true

다음 행은 가능하면 업스트림 분기가 있는 모든 분기를 빠르게 전달하고 그렇지 않으면 오류를 출력합니다.

git branch \
  --format "%(if)%(upstream:short)%(then)git push . %(upstream:short):%(refname:short)%(end)" |
  sh

어떻게 작동합니까?

에 사자형 사용다니합식을을 합니다.git branch분기가 과 같은됩니다.업스트림 분기가 있는 각 분기에 대해 다음 패턴이 있는 선이 인쇄됩니다.

git push . <remote-ref>:<branch>

은 이파프를직수연있다니습할결접이▁into다에 직접 파이프로 연결될 수 있습니다.sh(지점 이름의 형식이 올바른지 확인).략을 합니다.| sh그것이 무엇을 하는지 보기 위해.

주의사항

원라이너는 사용자의 리모컨에 연결하지 않습니다.를 발행합니다.git fetch또는git fetch --all실행하기 전에.

현재 체크아웃된 지점은 다음과 같은 메시지로 업데이트되지 않습니다.

! [remote rejected] origin/master -> master (branch is currently checked out)

, 은 정기적으로 이위해정,당은적으로기에 수.git pull --ff-only.

별칭

다을추다니에 합니다..gitconfig 그 록도하록git fft명령을 합니다.

[alias]
        fft = !sh -c 'git branch --format \"%(if)%(upstream:short)%(then)git push . %(upstream:short):%(refname:short)%(end)\" | sh' -

내 항목도 참조하십시오.별칭은 "지점을 빨리 감기(fast-forward tracking)"의 약어입니다.

refs/heads/master를 refs/remote/foo/master로 빠르게 전달할 수 있는 경우 출력은

git merge-base refs/heads/master refs/remotes/foo/master

참조/헤드/마스터가 가리키는 SHA1 ID를 반환해야 합니다.이를 통해 커밋이 적용되지 않은 모든 로컬 분기를 자동으로 업데이트하는 스크립트를 작성할 수 있습니다.

이 작은 셸 스크립트(저는 git-can-ff라고 부릅니다)는 이 작업이 어떻게 수행될 수 있는지를 보여줍니다.

#!/bin/sh

set -x

usage() {
    echo "usage: $(basename $0) <from-ref> <to-ref>" >&2
    exit 2
}

[ $# -ne 2 ] && usage

FROM_REF=$1
TO_REF=$2

FROM_HASH=$(git show-ref --hash $FROM_REF)
TO_HASH=$(git show-ref --hash $TO_REF)
BASE_HASH=$(git merge-base $FROM_REF $TO_REF)

if [ "$BASE_HASH" = "$FROM_HASH" -o \
     "$BASE_HASH" = "$FROM_REF" ]; then
    exit 0
else
    exit 1
fi

Matt Connolly의 답변을 완료하려면 지점을 체크아웃하지 않고 빠르게 전달할 수 있는 로컬 지점 참조를 더 안전하게 업데이트할 수 있습니다.빠르게 전달할 수 없는 분기(즉, 분기된 분기)는 업데이트하지 않으며, 현재 체크아웃된 분기(작업 복사본도 업데이트해야 하므로)도 업데이트하지 않습니다.

git fetch

head="$(git symbolic-ref HEAD)"
git for-each-ref --format="%(refname) %(upstream)" refs/heads | while read ref up; do
    if [ -n "$up" -a "$ref" != "$head" ]; then
        mine="$(git rev-parse "$ref")"
        theirs="$(git rev-parse "$up")"
        base="$(git merge-base "$ref" "$up")"
        if [ "$mine" != "$theirs" -a "$mine" == "$base" ]; then
            git update-ref "$ref" "$theirs"
        fi
    fi
done

@larsmans의 스크립트는 약간 개선되었습니다.

#!/bin/sh

set -x
CURRENT=`git rev-parse --abbrev-ref HEAD`
git fetch --all
for branch in "$@"; do
  if ["$branch" -ne "$CURRENT"]; then
    git checkout "$branch" || exit 1
    git rebase "origin/$branch" || exit 1
  fi
done
git checkout "$CURRENT" || exit 1
git rebase "origin/$CURRENT" || exit 1

작업이 완료되면 스크립트가 호출되기 전과 동일한 분기에서 작업 복사본을 체크아웃합니다.

git pull버전:

#!/bin/sh

set -x
CURRENT=`git rev-parse --abbrev-ref HEAD`
git fetch --all
for branch in "$@"; do
  if ["$branch" -ne "$CURRENT"]; then
    git checkout "$branch" || exit 1
    git pull || exit 1
  fi
done
git checkout "$CURRENT" || exit 1
git pull || exit 1

아래 스크립트를 사용하여 수행할 수 있습니다.먼저 모든 지점과 체크아웃을 하나씩 가져와 자동으로 업데이트합니다.

#!/bin/bash
git branch -r | grep -v '\->' | while read remote; do git branch --track 
"${remote#origin/}" "$remote"; done

set -x
CURRENT=`git rev-parse --abbrev-ref HEAD`
git fetch --all
branch_name=$(git branch | awk '{print $1" "}' | grep -v '*' | xargs)
for branch in $branch_name; do
   git checkout "$branch" || exit 1
   git rebase "origin/$branch" || exit 1
   git pull origin $branch|| exit 1
done
git checkout "$CURRENT" || exit 1
git pull || exit 1

많은 다른 사람들이 비슷한 해결책을 기여한 것처럼 보이지만, 저는 제가 생각해낸 것을 공유하고 다른 사람들이 기여하도록 초대해야겠다고 생각했습니다.이 솔루션은 다양한 색상의 출력을 제공하며 현재 작업 디렉토리를 우아하게 처리하며 체크아웃을 수행하지 않고 작업 디렉토리를 그대로 유지하기 때문에 속도가 빠릅니다.또한 git 외에는 의존성이 없는 셸 스크립트일 뿐입니다.(지금까지 OSX에서만 테스트됨)

#!/usr/bin/env bash

gitup(){    
RED='\033[33;31m'
YELLO='\033[33;33m'
GREEN='\033[33;32m'
NC='\033[0m' # No Color

HEAD=$(git rev-parse HEAD)
CHANGED=$(git status --porcelain | wc -l)

echo "Fetching..."
git fetch --all --prune &>/dev/null
for branch in `git for-each-ref --format='%(refname:short)' refs/heads`; do

    LOCAL=$(git rev-parse --quiet --verify $branch)
    if [ "$HEAD" = "$LOCAL" ] && [ $CHANGED -gt 0 ]; then
        echo -e "${YELLO}WORKING${NC}\t\t$branch"
    elif git rev-parse --verify --quiet $branch@{u}&>/dev/null; then
        REMOTE=$(git rev-parse --quiet --verify $branch@{u})
        BASE=$(git merge-base $branch $branch@{u})

        if [ "$LOCAL" = "$REMOTE" ]; then
           echo -e "${GREEN}OK${NC}\t\t$branch" 
        elif [ "$LOCAL" = "$BASE" ]; then
            if [ "$HEAD" = "$LOCAL" ]; then
                git merge $REMOTE&>/dev/null
            else
                git branch -f $branch $REMOTE
            fi
            echo -e "${GREEN}UPDATED${NC}\t\t$branch"
        elif [ "$REMOTE" = "$BASE" ]; then
            echo -e "${RED}AHEAD${NC}\t\t$branch"
        else
            echo -e "${RED}DIVERGED${NC}\t\t$branch"
        fi
    else
        echo -e "${RED}NO REMOTE${NC}\t$branch"
    fi
done
}

https://github.com/davestimpert/gitup

죄송합니다. 저도 위의 다른 도구와 같은 이름을 생각해 낸 것 같습니다.

이것이 괜찮은지는 모르겠지만, 여러 지점을 빨리 회송하려면 보통 전화를 호출합니다.

git pull origin master staging production

또한 여러 지점을 푸시하려면 전화를 겁니다.

git push origin master staging production

그러나 두 가지 모두 언급된 모든 분기가 병합할 필요가 없는 경우에만 작동합니다.

"git pull --all"이 모든 로컬 분기를 업데이트할 수 있습니까?

아니, 그럴 수 없어요.빠른 전달을 위해 작은 도구를 작성했습니다.https://github.com/changyuheng/git-fast-forward-all

이 도구의 장점:

  1. 하나의 저장소에서 여러 원격을 지원합니다.(hub sync현재 다중 원격을 지원하지 않습니다.)
  2. 로컬 분기와 해당 원격 추적 분기에 서로 다른 이름을 지정할 수 있습니다.
  3. 모든 분기에 대해 원격을 가져오는 다른 스크립트보다 훨씬 빠릅니다.
  4. 오류가 발생하기 쉬운 정규식 구문 분석/편집이 없습니다.

위의 답변 중 작업 트리가 여러 개일 가능성을 고려한 답변은 없습니다.분기 업데이트 중git update-ref또는git branch -f현재 다른 작업 트리에서 체크아웃된 경우 의도하지 않은 부작용이 발생합니다.

워크 트리를 처리하는 내 솔루션을 고려해 보십시오.

#! /usr/bin/env bash
set -euo pipefail

# Read the default remote from config, defaulting to "origin".
DEFAULT_REMOTE=$(git config --default origin --get clone.defaultRemoteName)

# Use first argument as remote name, fallback to default.
REMOTE=${1:-$DEFAULT_REMOTE}

# Resolve the rev that HEAD points at, so that we can give it
# a special treatment.
HEAD_REV=$(git rev-parse HEAD)

# Format that allows us to easily grep for local branches that are behind,
# and have an upstream at $REMOTE.
FORMAT="%(upstream:trackshort)%(upstream:remotename)|%(refname:short)"

# Get a list of revs that are checked out. We don't want to
# update refs that are pointing at them.
set +e
WORKTREE_REVS=$(git worktree list --porcelain | grep -Po "HEAD \K(.+)" | grep -v "$HEAD_REV")
set -e

git fetch $REMOTE

for BRANCH in $(git for-each-ref refs/heads --format="$FORMAT" | grep -Po "<$REMOTE\|\K(.+)")
do
    BRANCH_REV=$(git rev-parse $BRANCH)
    if [ "$BRANCH_REV" = "$HEAD_REV" ]
    then
        # This branch is currently checked out "here". Forward it carefully.
        set +e
        git merge --no-autostash --ff-only $BRANCH@{u}
        set -e
    elif grep -q "$BRANCH_REV" <<< "$WORKTREE_REVS"
    then
        # This branch is currently checked out by another. Leave it alone.
        echo "$BRANCH skipped, because it is checked out in another worktree. Use 'git worktree list' to diagnose."
    else
        # This branch is not checked out. Just update it!
        git update-ref refs/heads/$BRANCH $BRANCH@{u}
        echo "$BRANCH forwarded"
        fi
done

이 명령을 사용하면 도움이 됩니다.

for branch in `git branch | sed 's/\*//g'`; do git checkout $branch && git rebase origin/$branch; done

for branch in `git branch | sed 's/\*//g'`; do git checkout $branch && git reset --hard origin/$branch; done

for branch in `git branch | sed 's/\*//g'`; do git checkout $branch && git reset --hard origin/$branch && git pull; done

git 2.9 기준:

git pull --rebase --autostash

https://git-scm.com/docs/git-rebase 을 참조하십시오.

작업이 시작되기 전에 임시 스택을 자동으로 생성하고 작업이 종료된 후에 적용합니다.즉, 더러운 워크 트리에서 기본 재배치를 실행할 수 있습니다.그러나 주의하여 사용하십시오. 성공적인 기본 재배치 후 최종 스택 적용으로 사소한 충돌이 발생할 수 있습니다.

git 사실로, 로트.version 1.8.3.1작동합니다.

[root@test test]# git br
* master
  release/0.1
  update
[root@test test]# git pull --rebase
remote: Enumerating objects: 9, done.
remote: Counting objects: 100% (9/9), done.
remote: Compressing objects: 100% (9/9), done.
remote: Total 9 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (9/9), done.
From http://xxx/scm/csdx/test-git
   d32ca6d..2caa393  release/0.1 -> origin/release/0.1
Current branch master is up to date.
[root@test test]# git --version
git version 1.8.3.1

마스터 분기에서는 다른 모든 분기를 업데이트할 수 있습니다.@카스카벨

2.17(제가 사용하는)에서 어떤 버전의 고장/수리가 가능한지 모르겠습니다.

언급URL : https://stackoverflow.com/questions/4318161/can-git-pull-all-update-all-my-local-branches

반응형