"git pull"이 보류중인 변경 사항을 자동으로 숨기고 표시 할 수 있습니까?


122

나는 이것을 해결하는 방법을 안다.

user@host$ git pull
Updating 9386059..6e3ffde
error: Your local changes to the following files would be overwritten by merge:
    foo.bar
Please, commit your changes or stash them before you can merge.
Aborting

그러나 할 수있는 방법이 없다 git pull할 일 stashpop나를 위해 춤은?

이 명령의 이름이 다른 경우 괜찮습니다.

에 대한 셸 별칭을 만드는 것이 git stash; git pull; git stash pop해결책이지만 더 나은 해결책을 찾고 있습니다.


무엇에 대한 자식 별명?
Яois

20
git stash; git pull; git stash pop프로그래밍 방식으로 실행 하는 것은 위험합니다. 은닉 git stash할 것이 없으면 작동하지 않을 것이지만 git stash pop마지막 숨김 (있는 경우)을 표시하므로 거의 확실히 원하는 것이 아닙니다 . 사용자 torek이 Stack Overflow에 대한 훌륭한 게시물을 가지고 있지만 찾을 수 없습니다 ...
jub0bs


1
@guettli 나는 귀하의 질문이 중복임을 암시하지 않았으며 Jubobs의 의견에 대답했습니다.
VonC

2
한 단계 더 나아가, 당김 후 은닉 물을 깔끔하게 적용 할 수있는 경우에만 작업이 성공해야합니다. 충돌이 있으면 트리가 변경되지 않도록 전체 작업이 원자 적으로 실패합니다. 이것이 제가하고 싶은 것입니다. 로컬 변경 사항이 병합 된 상태에서 변경 사항을 풀다운하거나 오류가 발생하여 실패하고 다음에 수행 할 작업을 수동으로 결정할 수 있습니다. 이런 종류의 git '트랜잭션'이 가능합니까?
Ed Avis

답변:


185

Git 2.6 이상 (2015 년 9 월 28 일 릴리스)

그만큼 git config 흥미로운 설정은 다음과 같습니다.

rebase.autoStash

(Git 2.27, 2020 년 2 분기에는 이제 merge.autostash, 아래 참조)

true로 설정하면 작업이 시작되기 전에 자동으로 임시 숨김을 만들고 작업이 끝난 후에 적용합니다.
이는 더티 워크 트리에서 rebase를 실행할 수 있음을 의미합니다.

그러나주의해서 사용하십시오. 성공적인 리베이스 후 최종 숨김 애플리케이션은 사소한 충돌을 초래할 수 있습니다. 기본값은 false입니다.

그것을 다음과 결합하십시오.

pull.rebase

true이면 "git pull"이 실행될 때 기본 원격의 기본 브랜치를 병합하는 대신 가져온 브랜치 위에있는 브랜치를 리베이스합니다.

git config pull.rebase true
git config rebase.autoStash true

git pull더러운 나무에서도 간단 하게 작업 하기에 충분할 것 입니다.
이 경우 별칭이 필요하지 않습니다.


Kevin Daudt ( )의 commit 53c76dc (2015 년 7 월 4 일)를 참조하십시오 . (Merged by Junio ​​C Hamano -- in commit e69b408 , 17 Aug 2015)Ikke
gitster

pull: rebase.autostash활성화 되면 더티 트리 허용

rebase는 더러운 작업 트리를 만날 때 변경 사항을 숨기는 법을 배웠지 만 git pull --rebase그렇지 않습니다.

rebase.autostash활성화되지 않은 경우 작업 트리가 더러워 졌는지 확인하십시오 .


참고 : autostash 없이 가져 오려면 ( rebase.autoStash true이 설정되어 있어도 ) git 2.9 (2016 년 6 월)부터 다음이 필요합니다.

 pull --rebase --no-autostash

참조 450dd1d 커밋 , 1,662,297 커밋 , 44a59ff 커밋 , 5c82bcd 커밋 , 6ddc97c 커밋 , eff960b 커밋 , efa195d 커밋 (2016 4월 2일을), 및 f66398e 커밋 , c48d73b을 투입 하여 (2016년 3월 21일) Mehul 자이나교 ( mehul2029) .
(Merged by Junio ​​C gitsterHamano -- in commit 7c137bb , 13 Apr 2016)

특히 f66398e 커밋 에는 다음이 포함됩니다.

pull --rebase: --[no-]autostash플래그 추가

경우 rebase.autoStash구성 변수가 설정 "에 대한 재정의 할 수있는 방법이 없습니다 git pull --rebase명령 줄은".

설정된 경우 의 현재 값을 재정의 git pull --rebase하는 --[no-]autostash명령 줄 플래그를 " "에 알려줍니다 rebase.autoStash. " git rebase"이 --[no-]autostash옵션을 이해하므로 git rebase" git pull --rebase"이 호출 될 때 기본 " "에 옵션을 전달하는 문제입니다 .


경고 : Git 2.14 (2017 년 3 분기) 이전 git pull --rebase --autostash에는 로컬 기록이 업스트림으로 빠르게 이동할 때 " "가 자동으로 숨겨지지 않았습니다.

Tyler Brazier ( )의 commit f15e7cf (2017 년 6 월 1 일)를 참조하십시오 . (Merged by Junio ​​C Hamano -- in commit 35898ea , 05 Jun 2017)tylerbrazier
gitster

pull: ff --rebase --autostash는 더러운 저장소에서 작동합니다.

git pull --rebase --autostash더티 저장소에서 빨리 감기가 발생 했을 때 아무것도 자동 저장되지 않았고 가져 오기가 실패했습니다.
이것은 빨리 감을 수있을 때 rebase를 실행하지 않는 지름길 때문이지만 해당 코드 경로에서 autostash는 무시됩니다.


업데이트 : Mariusz Pawelski댓글 에서 흥미로운 질문을합니다.

그래서 모두가 autostash당신이 rebase (또는 pull --rebase) 를 할 때에 대해 쓰고 있습니다 .

그러나 병합을 사용 하여 정상적인 끌어 오기를 수행 할 때 아무도 자동 보관하지 않습니다 .
자동 스위치가 없나요? 아니면 뭔가 빠졌나요? 나는하는 것을 선호 git pull --rebase하지만 OP는 " standard "git pull

대답:

이 자동 숨김 기능을 설명 하는 원래 스레드 는 원래 git pull(병합) 및 git pull --rebase.

하지만 ... Junio ​​C Hamano (Git 관리자)는 다음과 같이 언급했습니다.

pull-merge이것이이 주제를 유발 한 "성가심"을 유발하는 것이면 정의에 따라 로컬 변경이 병합과 겹치고이 내부 "숨김 팝"이 병합이 터치 한 경로를 건 드리며 결과가 "떨어짐"이 아닐 가능성이 높습니다. "그러나 해결해야 할 갈등이 더 남아 있습니다.

pull.autostash구성이 좋지 않고 고통을 유발하는 워크 플로우를 장려하기 때문에 좋은 추가가 아니라고 생각합니다 .
단순한 경우에는 손상되지 않을 수 있지만 로컬 변경이 복잡한 경우에는없는 것보다 적극적으로 피해를 입을 수 있으며 구성은 선택의 인센티브를 앗아갑니다.

"pull-rebase"에 대한 방정식은 "rebase"가 깨끗한 작업 트리에서 시작하도록 요구하므로 "다운로드 후 중지"라는 성가심이 더 커집니다. 나는 실제 문제에 대한보다 생산적인 해결책이 될 수있는 느슨 함이 의심됩니다.

따라서 고전적인 풀 병합과 관련하여 다음을 수행하는 것이 좋습니다.

사용자가 " git pull" 를 실행하기 전에 작업 트리에있는 WIP의 특성에 대해 생각하도록 권장합니다 .
다른 사람들이하는 일을 방해 할 수있는 너무 복잡한 짐승입니까, 아니면 그가 숨겨서 다시 튀길 수있는 사소한 변화입니까?

전자의 경우 " checkout -b"을 수행하는 것이 훨씬 더 나을 것입니다 . 로컬 변경이 다소 더 나은 형태가 될 때까지 계속 작업하고 "커밋"한 다음 원래 지점으로 가져옵니다.

후자의 경우 다음을 수행하는 것이 좋습니다.

  • " git pull",
  • 충돌을 찾은 후 실행
    • git stash,
    • git merge FETCH_HEAD
    • git stash pop

즉, Git 2.27 (2020 년 2 분기)에서 " git pull" pull.rebase구성이 존재하지 --[no-]rebase않거나 --ff-only제공 되지 않을 때 경고하는 방법을 배웠습니다 (병합 결과).

Alex Henrie ( )의 commit d18c950 (2020 년 3 월 10 일)을 참조하십시오 . (Merged by Junio ​​C Hamano -- in commit 1c56d6f , 27 Mar 2020)alexhenrie
gitster

pull: 사용자가 리베이스할지 병합할지 여부를 말하지 않은 경우 경고

서명자 : Alex Henrie

종종 초보 Git 사용자는 " pull --rebase" 라고 말하는 것을 잊고 업스트림에서 불필요한 병합으로 끝납니다.

일반적으로 원하는 것은 pull --rebase간단한 경우 " pull --ff-only" 또는 주요 통합 분기의 복사본을 업데이트하고 작업을 별도로 리베이스하는 " "입니다. 구성 변수는 간단한 경우에 그들을 돕기 위해 존재하지만, 이러한 사용자가 인식하게하는 메커니즘이 없습니다.
pull.rebase

--[no-]rebase명령 줄에 옵션이없고 pull.rebase구성 변수가 제공 되지 않으면 경고 메시지를 발행합니다 . 특별한 조치를 취하지 않은
" pull --rebase"을 (를) 원하지 않는 사람들에게 불편 을 줄 수 있지만 불편한 비용은 사용자 당 한 번만 지불되므로 많은 신규 사용자를 돕기위한 합리적인 비용이되어야합니다.


Git 2.27 (2020 년 2 분기)에서 " git merge"는 " --autostash"옵션과 새로운 merge.autostash설정을 학습 합니다.

참조 d9f15d3 커밋 , f8a1785 커밋 , a03b555 커밋 , 804fe31 커밋 , 12b6e13 커밋 , 0dd562e 커밋 , 0816f1d 커밋 , 9bb3dea 커밋 , 4d4bc15 커밋 , b309a97 커밋 , f213f06 커밋 , 86ed00a 커밋 , facca7f 커밋 , be1bb60 커밋 , efcf6cf 커밋 , c20de8b 커밋 , 커밋 bfa50c2 , 커밋 3442c3d , 커밋 5b2f6d9 (2020 년 4 월 7 일), 커밋 65c425a(2020 년 4 월 4 일), 커밋 fd6852c , 커밋 805d9ea (2020 년 3 월 21 일) by Denton Liu ( Denton-L) .
(Merged by Junio ​​C gitsterHamano -- in commit bf10200 , 29 Apr 2020)

pull: 병합 할 --autostash 전달

서명자 : Denton Liu

이전 --autostash에는 git pull --rebase.

그러나 지난 패치에서 병합도 배웠 --autostash으므로 더 이상 이러한 제한을 가져야 할 이유가 없습니다. 리베이스에서와 마찬가지로
풀에서 패스 --autostash로 병합하여 병합 하도록 가르치십시오 .

과:

rebase: apply_autostash()sequencer.c에서 사용

서명자 : Denton Liu

apply_autostash()함수는 허용하는 인수 유형을 제외하고 거의 상호 교환이 가능하다는 점 builtin/rebase.c에서 apply_autostash()함수 와 유사 sequencer.c합니다. sequencer.cextern 버전을 만들고 rebase에서 사용하십시오.

rebase 버전은 6defce2b02 ( "builtin rebase : support --autostashoption", 2018-09-04, Git v2.20.0-rc0- merge list in batch # 8 )에서 쉘에서 C 로의 변환의 일부로 도입되었습니다.
당시에는 대화 형 리베이스를 셸에서 C로 변환하는 또 다른 진행중인 프로젝트가 있었기 때문에 함수를 복제하기로 결정했으며 .NET Framework sequencer.c버전을 리팩토링하여 충돌을 원하지 않기 때문 입니다 apply_autostash().
두 가지 노력이 오랫동안 이루어 졌으므로 이제 자유롭게 결합 할 수 있습니다.


2.4.2부터는 아직 구현되지 않았습니다. 아마도 언젠가. rebase.autoStashrebase를 사용할 때만 적용됩니다. pull.rebase당기기를 사용할 때만 적용됩니다.
Randal Schwartz

"더러운 나무에서도 간단한 git pull이 작동하기에 충분할 것입니다." Randal이 말했듯이 이것은 아직 사실이 아닙니다. 현재 마스터의 pull.c는 여전히 die_on_unclean_work_tree.
Pradhan

1
@Pradhan 동의합니다. 구현은 오늘 아침에 마스터에 도착했으며 git 2.6에 맞춰야합니다. 나는 그것을 명확하게하기 위해 대답을 편집했습니다.
VonC

autostash가 git과 함께 작동하고 있음을 확인했습니다 2.5.5.
Joshua Hoblitt

1
모두가 autostash에 대해 쓰고있다 그래서 당신이 할 때 rebase(또는 pull --rebase). 그러나 pull병합을 정상적으로 수행 할 때 아무도 자동 숨김을 사용하지 않습니다 . 자동 스위치가 없나요? 아니면 뭔가 빠졌나요? 나는 일을 선호 git pull --rebase하지만, 영업 이익은 "표준"에 대해 질문git pull
MARIUSZ Pawelski

41

다가오는 탐험가를 위해 몇 초를 절약하기 위해 다음은 요약입니다 (@VonC 덕분에).

git pull --rebase --autostash

6
요점은 다음 git config pull.rebase true과 같습니다. a 및 뒤에 git config rebase.autoStash true필요한 것은 git pull. 그냥 git pull. 다른 옵션이 필요하지 않습니다.
VonC

3
--autostash옵션에 대해 Git 2.9 이상이 필요합니다 . 는 -c rebase.autoStash=true이후 힘내 2.6에서 작동합니다.
ntc2 2017

15

위의 설명에서 언급했듯이 git pullautostash 구성은 실제 rebase에만 적용 되므로 두 구성 값을 설정하는 것은 현재에서 작동하지 않습니다 . 이 git 명령은 원하는 작업을 수행합니다.

git fetch
git rebase --autostash FETCH_HEAD

또는 별칭으로 설정하십시오.

git config alias.pullr '!git fetch; git rebase --autostash FETCH_HEAD'

다음을 수행하십시오.

git pullr

물론이 별칭은 원하는대로 이름을 바꿀 수 있습니다.


7

Git 2.6 이상에서는 다음을 사용할 수 있습니다.

alias gup='git -c rebase.autoStash=true pull --rebase'

이로 --rebase인해 git-pull rebase대신을 사용 merge하므로 설정 / 옵션 --ff-only이 적용되지 않습니다.

--ff-only기본적 으로 가져 오기 위해 별칭을 사용하고 있으며 ( git pull --ff-only), gup빨리 감기 병합이 불가능하거나 숨겨진 변경 사항이있는 경우 (위에서) 사용할 수 있습니다 .


git pull --ff-only과 의 주요 차이점은 무엇입니까?git pull pull --rebase --autostash
alper

0

이미 언급했듯이 이것이 수행하는 방법입니다. 별칭에서 사용하여 입력을 저장하고 바로 가기를 사용하거나 한 줄로 사용할 수 있습니다 (별칭 일 수도 있음).

git stash && git pull --rebase && git stash pop

그것은 당신이 한 것과 똑같은 일을 할 것이지만 한 줄 (&&)에서 별칭으로 설정하면 더 짧아 질 것입니다.

다음 줄은 당기기 / 밀기 전에 들어오는 / 나가는 변경 사항을 표시합니다.

git log ^master origin/master
git log master ^origin/master

8
이 접근 방식은 안전하지 않습니다. 숨길 것이 없으면 첫 번째 명령은 아무 작업도 수행하지 않고 stash pop이전에 가져온 임의의 항목을 해제합니다.
John Zwinck

그냥 명확 추가 할 수 있습니다 : 경우에도 git stash&& 여전히 계속 않도록 숨겨 놓은 것도이 여전히 "반환"아니오 에러 코드를하지 않는 git pullgit stash pop및 이전 숨겨 놓은 팝업. 따라서 무언가를 숨길 것이라는 확신이 없으면 이것을 사용하지 않는 것이 좋습니다!
MoonLite
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.