-
[Git] 특정 브랜치에서 main(master) 브랜치 merge(push) 막기저장소/git 2022. 7. 3. 15:45
특정 브랜치에서 main 또는 master 브랜치에 merge 또는 push되는 것을 막는 방법을 설명합니다.
- 아래 설명에서는 develop → main이 되지 않도록 예시를 듭니다.
github branch protection rule 추가
repository에서 Settings → Branches에 들어간 다음 Branch protection rules 에서
Add rule
을 클릭합니다.그 다음, Branch name pattern에 아래의 룰을 적용할 패턴을 추가하고 (여기서는 main 브랜치명을 그대로 적습니다.)
Require a pull request before merging
을 체크합니다.체크하면 하위 리스트가 나오게 되는데
Require approvals
를 체크해제 하지 않고 몇명의 approval을 받아야만 PR을 머지할 수 있는지 세팅해 줍니다.여기서는 1명 이상이 approval을 해야만 머지가 되도록 설정했습니다.
이 방법의 문제는 해당 repository의 administrator 라면 강제로 PR을 할 수 있다는 점입니다.
github action 추가
다음 방법으로는 gitgub action을 추가하여 PR이 등록되었을 때, 알림을 주는 방식입니다. 해당 방식 또한 실패했다고 해서 PR을 막을 순 없습니다. (강제성X)
main 브랜치에서 아래의 코드를
.github/workflows/{파일명}.yml
에 추가합니다.name: Restrict merge from develop to main on: pull_request: branches: [ main ] jobs: check-compare-branch: runs-on: ubuntu-latest steps: - name: Check compare branch run: | # PR 소스 브랜치가 develop일 경우, 실패 그 외의 브랜치면 통과 if [[ "$GITHUB_HEAD_REF" == 'develop' ]]; then exit 1; else exit 0; fi;
서버에 반영을 한 다음, 해당 github repository의 Actions를 들어가면 name으로 지정한 workflow가 생성된 것을 볼 수 있습니다.
develop 브랜치에서 main으로 PR을 등록하면 테스팅이 실패한 것을 볼 수 있습니다.
위에서 설명한 것 처럼 실패해도
Merge pull request
버튼을 눌러 main에 머지를 할 수 있습니다.로컬 git hook 추가하기
githook을 사용하여 main(master) 브랜치에 특정 브랜치가 merge가 되는 상황을 방지할 수 있습니다.
- 적용할 repository의 디렉토리에서
.git/hooks/
로 이동한 다음prepare-commit-msg
파일을 생성합니다. - 아래의 코드를 추가하고 저장한 다음, 편집기를 종료합니다.
#!/usr/bin/env ruby # This git hook will prevent merging specific branches into master # Put this file in your local repo, in the .git/hooks folder # and make sure it is executable. # The name of the file *must* be "prepare-commit-msg" for Git to pick it up. FORBIDDEN_BRANCHES = ["develop"] def merge? ARGV[1] == "merge" end def into_master? current_branch = `git branch | grep '*' | sed 's/* //'`.chop current_branch == "master" end def merge_msg @msg ||= `cat .git/MERGE_MSG` end def from_branch @from_branch = merge_msg.match(/Merge branch '(.*?)'/)[1] end def from_forbidden_branch? FORBIDDEN_BRANCHES.include?(from_branch) end if merge? && into_master? && from_forbidden_branch? out = `git reset --merge` puts puts " STOP THE PRESSES!" puts " You are trying to merge #{from_branch} into the *master* branch." puts " Surely you don't mean that?" puts puts " run the following command now to discard your working tree changes:" puts puts " git reset --merge" puts exit 1 end
- 해당 파일의 권한을 다음과 같이 설정합니다.
chmod +x .git/hooks/prepare-commit-msg
- merge option을 수정했다면 다음의 명령어를 실행합니다.
git config branch.master.mergeoptions "--no-ff"
위의 단계를 전부 적용했다면 develop 브랜치를 master 브랜치에 머지를 하려고 할 때, 실패가 발생하게 됩니다. 실패가 됐다면 여전히 merge 상태이므로
git reset --merge
를 입력하여 되돌려줘야 합니다.해당 방법의 문제는 로컬에서만 막는 것이므로 github에서는 여전히 강제로 PR 후 머지가 가능합니다.
결론
github을 사용하고 관리자 권한이 있다면 사실상 완벽하게 막는 방법은 없다
레퍼런스