Git Stash를 워크 플로우로 사용하는 것은 반 패턴입니까? 작동하는 기능 분기 워크

최근에 나와 팀에서 Git을 사용하는 방법과 워크 플로 작동 방식을 살펴 보았습니다. 현재 잘 작동하는 기능 분기 워크 플로를 사용하고 있습니다.

또한 팀의 일부 개인이 git stash 기반 워크 플로를 사용하는 것을 보았습니다 . 워크 플로는 다음과 같습니다.

  • 메인 지점에서 작업 (예 master🙂
  • 당신이 갈 때 커밋
  • 변경 사항을 가져 오거나 분기를 전환해야하는 경우 커밋되지 않은 변경 사항을 숨김으로 푸시하십시오.
  • 업데이트가 완료되면 변경 사항을 숨김에서 제거하십시오.

이 워크 플로는 기능 분기 워크 플로 대신 사용 됩니다 . 지점을 가져 와서 작업하는 대신 여기에서 개발자는 단일 지점에서만 작업하고 스택에서 푸시 / 팝을 맞습니다.

실제로 이것이 훌륭한 워크 플로우라고 생각하지 않으며 이런 방식으로 git stash를 사용하는 것보다 분기가 더 적합합니다. git stash의 가치를 긴급 작업으로 볼 수 있지만 일상적인 일상 워크 플로에서 사용하지는 않습니다.

git stash를 정기적으로 사용하는 것이 반 패턴으로 간주됩니까? 그렇다면 발생할 수있는 특정 문제는 무엇입니까? 그렇지 않다면 어떤 이점이 있습니까?



답변

로부터 망할 놈의 SCM 예약 :

종종 프로젝트의 일부에서 작업 할 때 상황이 지저분하고 분기가 다른 작업을 수행하도록 전환하려고 할 때가 있습니다. 문제는, 당신은 나중에이 시점으로 돌아갈 수 있도록 반 완료 일을 저지르고 싶지 않다는 것입니다. 이 문제에 대한 답은 git stash 명령입니다.

스 태싱은 작업 디렉토리의 더티 상태 (즉, 수정 된 추적 파일 및 단계적 변경 사항)를 취하여 언제든지 다시 적용 할 수있는 완료되지 않은 변경 사항 스택에 저장합니다.

이 설명이 주어지면 이것이 안티 패턴이라고 말할 것입니다. Git Stash에 대해 지나치게 단순화 된 설명은 소스 제어의 “잘라 내기 및 붙여 넣기”라는 것입니다. 변경된 파일을 여러 개 가져 와서 Git의 일반적인 브랜칭 워크 플로우 외부의 홀딩 펜에 “스태킹”한 다음 나중에 해당 변경 사항을 다른 브랜치에 다시 적용합니다.

조금 더 되돌아 가면 마스터에 헌신하는 것이 반 패턴 입니다. 가지를 사용하십시오. 그것이 그들이 디자인 한 것입니다.

실제로 이것으로 요약됩니다.

벽에 나사를 망치면 그림이 표시되지만 드라이버를 사용하는 것이 좋습니다. 드라이버가 바로 옆에 앉아있을 때 망치를 사용하지 마십시오.

“깨진”코드 커밋 정보

다음은 의견이지만,이 의견은 경험으로부터 왔습니다.

일찍 커밋하고 자주 커밋하십시오. 원하는만큼 깨진 코드를 커밋하십시오. 무언가를 해킹하는 동안 지역 커밋 기록을 “저장 포인트”로보십시오. 논리적으로 작업 한 후에는 커밋을 수행하십시오. 물론 모든 것을 망칠 수는 있지만 커밋을 푸시 하지 않는 한 중요하지 않습니다 . 푸시하기 전에 커밋을 리베이스하고 스쿼시하십시오.

  1. 새로운 지점 만들기
  2. 해킹 해킹 해킹
  3. 깨진 코드 커밋
  4. 코드를 연마하고 작동 시키십시오
  5. 작업 코드 커밋
  6. 리베이스와 스쿼시
  7. 테스트
  8. 테스트 통과시 푸시

OP의 경우,이 Linux 커널 메시지 스레드 는 OP 팀의 일부 구성원이 비슷한 방식으로 Git을 사용하는 것처럼 들리기 때문에 관심이있을 수 있습니다.

@RibaldEddie는 아래의 코멘트에서 말했다 :

우선, 숨김은 “브랜칭 워크 플로우”외부에 있지 않습니다.

(많은 사람들의 분노가 발생할 위험이 있음)

리누스는 말했다 :

“git stash”를 사용하면 여러 가지 숨김 항목을 가질 수 있지만 서로 대기열에 있지는 않습니다. 즉, 언젠가 불편했기 때문에 숨겨둔 임의의 독립 패치 일뿐입니다.

@RibaldEddie가 말하려는 것은 git stash기능 분기 워크 플로에서 사용할 수 있다는 것 입니다. 사용하지 않습니다git stash 문제가 아닙니다. 이는 마스터 커밋과 사용의 조합입니다 git stash. 이것은 안티 패턴입니다.

명확화 git rebase

@RibaldEddie의 의견에서 :

Rebasing은 복사-붙여 넣기 훨씬 비슷 하며 커밋 된 기록을 더 나쁘게 수정합니다.

(엠파 시스 마인)

커밋 히스토리 수정은 로컬 커밋 히스토리 인 한 나쁘지 않습니다 . 이미 푸시했다는 커밋을 리베이스하면 본질적으로 브랜치를 사용하는 다른 사람을 고아 할 것입니다. 이것은 나쁘다.

이제 하루 동안 여러 번 커밋했다고 가정 해보십시오. 일부 커밋은 좋았습니다. 일부는 … 너무 좋지 않습니다. 그만큼git rebase커밋을 부수 명령과 함께 해당 지역의 커밋 역사를 정리하는 좋은 방법입니다. 팀의 공유 지점의 커밋 기록을 깨끗하게 유지하기 때문에 하나의 커밋을 퍼블릭 브랜치에 병합하는 것이 좋습니다. rebasing 후 다시 테스트하고 싶지만 테스트에 통과하면 더티 커밋 대신 하나의 클린 커밋을 푸시 할 수 있습니다.

클린 커밋 히스토리 에는 또 다른 흥미로운 Linux Kernel 스레드 가 있습니다 .

다시 Linus에서 :

나는 깨끗한 역사를 원하지만 그것은 실제로 (a) 깨끗하고 (b) 역사를 의미합니다.

사람들은 개인 나무 (자신의 작업)를 리베이스 할 수 있습니다 . 그것은 정리 입니다. 그러나 다른 사람들은 코딩하지 않습니다. 그것은 “파괴 역사”입니다

따라서 역사 부분은 매우 쉽습니다. 하나의 주요 규칙과 하나의 작은 설명이 있습니다.

  • 다른 민족의 역사를 절대로 파괴해서는 안됩니다. 다른 사람이 저지른 커밋을 리베이스해서는 안됩니다. 기본적으로 사인 오프가없는 경우 오프 오프입니다. 본인이 아니기 때문에 리베이스 할 수 없습니다.

    이것은 다른 민족의 코드가 아니라 다른 민족의 역사 에 관한 것 입니다. 그들이 이메일로 패치 된 것을 당신에게 보내었고 “git am -s”로 그것을 적용했다면, 그것은 그들의 코드이지만
    당신의 역사입니다.

    커밋 자체가 개인 코드 인 한 코드를 작성하지 않았더라도 “git rebase”에 열중 할 수 있습니다.

  • 규칙에 대한 사소한 설명 : 일단 어떤 공개 사이트에 역사를 게시하면 다른 사람들이이를 사용하고있을 수 있으므로 이제는 더 이상 개인 역사가 아닙니다 .

    따라서 약간의 설명은 실제로 “커밋”에 관한 것이 아니라 나무에 대한 개인 정보에 관한 것이며, 아직 공개하지 않았으며 발표하지 않았다는 것입니다.

“깨끗한”부분은 좀 더 미묘하지만 첫 번째 규칙은 매우 분명하고 쉽습니다.

  • 자신의 역사를 읽을 수있게 유지

    어떤 사람들은 먼저 머릿속에서 일을하고 실수를하지 않음으로써 이것을합니다. 그러나 그것은 매우 드문 일이며, 우리는 문제 해결을 위해 “git rebase”등을 사용합니다.

    따라서 “git rebase”는 틀리지 않습니다. 그러나 그것은 당신이 당신의 개인 프라이 비트 자식 트리 인 경우에만 맞습니다.

  • 쓰레기를 노출시키지 마십시오.

    즉, 여전히 “git rebase”단계에 있다면 푸시하지 않습니다. 준비가되지 않았다면 패치를 보내거나 대중에게 알리지 않는 개인 git 트리 ( “패치 시리즈 대체”)를 사용하십시오.

(강조 광산)

결론

결국 OP에는 일부 개발자가 다음을 수행합니다.

git checkout master
(edit files)
git commit -am "..."
(edit files)
git stash
git pull
git stash (pop|apply)

여기에는 두 가지 문제가 있습니다.

  1. 개발자는 마스터하기 위해 노력하고 있습니다. 이것을 즉시 잠그십시오. 실제로 이것은 가장 큰 문제입니다.
  2. 기능 분기를 사용해야 할 때 개발자는 지속적으로 사용 git stash하고 git pull있습니다.

Git에서 더 나은 워크 플로우가있을 때 git stash특히-끌어 오기 전에- 를 사용하는 데 아무런 문제가 없지만 git stash이 방식으로 사용 하는 것은 반 패턴입니다.

의 사용 git stash붉은 청어. 문제가 아닙니다. 마스터하는 것은 문제입니다.


답변

개인적 stash으로 다른 지점으로 변경해야하는 질문을하는 사람처럼 짧고 예기치 않은 중단 에만 개인적으로 사용 합니다. 나는 이전에 숨김을 잊어 버렸으므로 깨끗하게 적용되지 않기 때문에이 작업을 수행합니다. 기능 브랜치에 대한 정기적 커밋은 잊기 어렵고 병합하기가 더 쉬워 졌으므로 이제는 커밋 된 커밋을 한 다음 git reset HEAD~1나중에 유지하고 싶지 않으면 리베이스 를 수행하는 경향이 있습니다 .

그러나 분산 버전 제어의 장점은 공유 리포지토리가 표준을 충족하는 한 사람들이 자신의 리포지토리에서 원하는 워크 플로를 사용할 수 있다는 것입니다. stash대안에 대한 충분한 교육이나 인식이 없기 때문에 사람들이 워크 플로를 사용 하지 않도록해야하지만 여전히 워크 플로를 선택하면 차선책을 찾을 수 있습니다.


답변

안티 패턴 인 귀하의 질문 중 일부는 단일 공유 마스터 분기를 사용하는 것입니다. 그러나 마스터 브랜치 외에 개발 브랜치 를 포함한 다음 스 태쉬를 사용하여 개발 브랜치에서 자체 컨텍스트 스위치를 처리하는 경우 이는 반 패턴이 아니며 일부 워크 플로우를 매우 밀접하게 반영합니다. Etsy 및 Facebook과 같은 조직에서 설명합니다.

위의 @Greg Burghardt의 대답은 소위 git-flow 또는 feature-branch 워크 플로우에 약간 유리합니다. 나는 비슷한 전략을 옹호 해 왔지만 그것이 불필요한 복잡성을 더하고 잘못된 보안 감각을 만든다는 것을 깨달은 후에는 더 이상하지 않는다. 또한 서브 버전과 같은 비분 산형 버전 제어 시스템의 시대에 이어지고 있습니다.

먼저 Git은 Subversion과 달리 분산 버전 관리 시스템이므로 개발자의 로컬 저장소는 본질적으로 코드 자체의 거대한 지점입니다. 개별 개발이 로컬에서 수행하는 작업은 부서 지거나 버그가있는 코드가 공유 저장소의 공유 지점으로 푸시되지 않는 한 다른 팀 구성원에게 영향을 미치지 않아야합니다.

그러나 rebase 명령은 재생 된 커밋 중 하나에 병합 충돌이있을 때 분기 기록을 손상시킬 수 있습니다. 에서 http://ryantablada.com/post/the-dangers-of-rebasing-a-branch

나머지 rebase는 원활하게 진행되며 테스트는 모두 통과하는 것 같습니다. 홍보가 이루어집니다.

그리고 commentForAllPosts 속성에 의존하는 코드가 더 작성되고 모든 것이 깨졌습니다. 그러나 우리는 누구에게 가서 도움을 요청합니까? git blame은 코드 라인이 서버 측 엔지니어에 의해서만 작성되었으며 손을 내밀 었다는 것을 보여줍니다.

이제 프론트 엔드 엔지니어가 휴가 중이거나 병가에 있거나 아는 사람이 있습니다. 아무도 그 코드가 어떻게 생겼는지 알 수 없습니다!

Rebase는 하위 분기의 병합 충돌이 사라지고 원래 코드가 영원히 손실되기 때문에 무엇이 잘못되었는지 찾기 위해 팀의 기록을 살펴볼 수 없게되었습니다.

이 동일한 병합 충돌이 발생하여 병합이 사용 된 경우, 책임은 병합 프로세스, 상위 분기의 커밋 및 하위 분기의 커밋에서 해당 코드 줄이 터치되었음을 나타냅니다. 일부는 세 가지 순열을 가지고 놀면서 원래의 의도를 코드베이스로 되돌려 놓고 많은 손가락으로 손가락을 긁지 않고 작업 할 수 있습니다. 그리고 당신이 정말로 가진 것은 또 다른 커밋이었습니다.

또한 다중 분기 모델에서는 두 분기가 상호 의존적 코드 변경을 포함 할 수 없다고 가정합니다. 그것이 불가피하게 일어날 때, 개발자는 이제 효율적으로 작업하기 위해 더 많은 지점을 저글링해야합니다.

내가 본 기본 반 패턴은 가지 대 스 태쉬와 관련이 없지만 오히려 매우 똑똑한 사람들이 한동안 이야기 해 온 문제의 종류에 관한 것입니다. 단위 테스트와 좋은 아키텍처? 개발자가 변경 사항을 쉽게 추론하고 변경 내용을 이해할 수 있도록 코드를 점진적으로 변경할 수 있습니까? 개발자가 실제로 작동하는지 확인하기 위해 새 코드를 한 번 실행합니까? (예, 전에 본 적이 있습니다).

이러한 질문에 대한 대답이 ‘아니오’라면 실제로 얼마나 많은 브랜치가 있는지는 중요하지 않습니다. 개발자는 코드가 준비가되어 있고 작동하지 않으며 프로덕션 환경에 적합하지 않으며 브랜치가 많지 않다고 말할 것입니다. 어쨌든 해당 코드가 프로덕션 환경에 올라갈 때 도움이됩니다.


답변

git stash도구입니다. 그것은 그 자체가 패턴이나 반 패턴이 아닙니다. 망치와 같은 도구입니다. 망치를 사용하여 못을 박는 것은 패턴이며 망치를 사용하여 나사를 박는 것은 반 패턴입니다. 마찬가지로, git stash올바른 도구를 사용하는 워크 플로 및 환경과 워크 플로 및 환경이 잘못되었습니다.

‘모든 사람의 커밋과 추진’워크 플로는 위험이 크게 변하지 않는 곳에서 상당히 합리적으로 작동하는 워크 플로입니다. 종종 코드가있는 권위있는 중앙 서버가있는 svn 환경에서 사용됩니다.

그러나 Git은 하나의 중앙 서버와 관련이 없습니다. 하고 모든 개발자를 갖는 commit, pull(또는 rebase당신이로 인 경우), push모든 시간은 큰 혼란을 만들 수 있습니다.

가장 큰 문제는 깨진 무언가가 진행 중이며 우선 순위 버그를 해결해야한다는 것입니다. 즉 , 이전 작업을 진행 하지 않고도 작업을 조금만 치워두고 최신 작업을 수행하고 작업해야한다는 것을 의미합니다 .

이를 위해서는 git stash적절한 도구가 사용됩니다.

그러나이 워크 플로우의 핵심에는 더 큰 문제가 있습니다. 라는 것이다 모든 버전 제어 지점의 역할이 하나의 지점에 있습니다. 메인 라인, 개발, 유지 보수, 축적 및 포장은 모두 마스터에 있습니다. 이것은 문제입니다. ( 이 지점에 대한이 접근 방식에 대한 자세한 내용은 고급 SCM 지점 전략 을 참조하십시오 )

그렇습니다. 훌륭한 워크 플로가 아니며 문제가 있음을 지적했습니다. 그러나 문제는 도구와 관련이 없습니다 git stash. 문제는 역할 또는 호환되지 않는 정책에 대한 뚜렷한 분기가 없다는 것입니다 .

git stash그러나, 내가 조금 빌드 한 상황에서 올바른 상태인지 확실하지 않은 끈적 끈적한 상태에 있었을 때 사용했던 것입니다 … 그래서 나는 변화를 막았습니다. 그런 다음이 문제를 해결하기위한 다른 접근 방법을 탐색했습니다. 그것이 효과가 있었다면, 잘 보관 된 물건을 버리고 계속하십시오. 다른 탐사가 더 끈적 끈적했다면 이전 변경 사항으로 다시 재설정하고 숨김을 다시 적용하십시오. 대안은 커밋, 체크 아웃, 분기 한 다음이 새로운 분기를 계속하거나 돌아가서 재설정하는 것입니다. 문제는 내가 조금만 탐색하고 싶을 때 역사에 넣을 가치가 있다는 것입니다.

git stash안티 패턴이 아닙니다. 사용git stash모두가 마스터에게 커밋하는 동안 브랜치의 대안으로 하는 것은 반 패턴입니다 git stash.

아직 히트하지 않았다면 누군가 빌드 파일에 문제가 생길 때까지 기다리십시오. 누군가가 많은 파일 (및 병합 충돌)에 대해 아키텍처를 크게 변경해야하거나 테스트를 거치지 않은 테스트 작업 중 코드가 프로덕션으로 유출되는 경우 당신을 따라 잡을 안티 패턴.


답변