외부 모듈을 git로 처리하는 방법 (subtree)

12325 단어 Git

개요


예를 들어, 웹 페이지를 작성하는 프로젝트 A 프로젝트 B가 있다고 가정합니다.
전혀 다른 항목이지만 CSS만 같은 걸 쓰려고 해요.
충실 CSS를 끊임없이 업데이트하고 싶습니다.
그리고'프로젝트 C'를 새로 제작할 때도 이 CSS를 사용하고 싶었다.
git는 이를 실현하는 메커니즘을 갖추고 있다.
'subtree'의 구조입니다.

위의 그림에서 보듯이git가 관리하는'프로젝트 A'에는 다른git창고'CSS'도 관리하고 있다.
'CSS'에 기능을 추가하고 이를 CSS 창고에 PUSH로 옮긴 후'프로젝트 B'에서도 기능이 추가된 CSS를 사용할 수 있다.
물론 거꾸로 할 수도 있다.

사이트 축소판 그림


git subtree의 연습 - Weblog-Hail2u.net
git subtree 사용해 봤습니다. - Qiita.
위의 사이트에도 git 버전에 따라 다양한 방법이 있는 것 같다고 쓰여 있다.
git1.7의 중도에subtree를 가져왔습니다. 버전 1.8 이후에는 이번 방법으로도 가능합니다. (미검증)git subtree -h 명령을 입력하고 도움말을 표시하면 사용할 수 있습니다.
참고로 아래의 사이트 정보는 좀 낡았으니 주의하세요.
Giit - 하위 트리 결합
How to use the subtree merge strategy

subtree 사용 방법


그럼 실제로 해보세요.
예를 들어, 프로젝트에 CSS 저장소에 기록합니다.

미리 준비하다


외부 창고를 현재 프로젝트로 하위 디렉터리로 가져옵니다.
외부 창고를 저장소로 등록합니다.git remote add <name> <url> <name>의 부분에 적당한 이름을 넣다.cssrepo라고 가정하십시오.<url>는 CSS 웨어하우스의 URL입니다.

subtree add


이 명령을 사용하면 외부 창고를 하위 디렉터리로 프로젝트에 포함할 수 있습니다.
shell
git subtree add   --prefix=<prefix> --squash <repository> <commit>
<prefix> 캡처할 디렉토리의 이름을 지정합니다.
새로 만들기 때문에 기존 디렉터리 이름을 덮어쓰지 마십시오.
예를 들어, "css"디렉토리 이름을 지정하려면 [css]를 입력합니다.
[modules] 디렉터리에 있는 [css] 디렉터리를 만들려면 [module/css]로 하십시오.
여기에 마지막에 슬래시를 넣으면 이후에 순조롭게 진행될 수 없으니 주의하세요.<repository>는 이전에 등록하려고 했던 창고 이름이다.
이때는 [cssrepo]입니다.<commit> 부분은 도움말에서commiit이지만 지점 이름도 가능합니다.
이번에는 [마스터].--squash 옵션을 설정하면 기록을 계승하지 않고 얻을 수 있습니다.

example


shell
% git subtree add --prefix=modules/css --squash cssrepo master
git fetch cssrepo master
From /Users/hoge/git/tests/css
 * branch            master     -> FETCH_HEAD
Added dir 'modules/css'

subtree push


다음에 프로젝트에서 얻은 css를 업데이트해서push를 진행합니다.
push 전에commiit가 필요하지만 이것은 일반적으로 하면 됩니다.
git commit -m 'h1タグのcolorがgoldになるように更新' -a
아래와 같은 추가subtree 디렉터리만 push할 수 있습니다.
shell
git subtree push  --prefix=<prefix> --squash <repository> <refspec...>
<prefix> 캡처할 디렉토리의 이름을 지정합니다.
dd와 같다.마지막으로 빗장을 넣지 않도록 주의해라.<repository> 외부 창고 명칭.이때는 [cssrepo]입니다.<refspec...> [로컬 분기 이름: 원격 저장소 이름]
콜론을 생략하면 로컬과 원격 모두 같은 지점을 지정합니다.
참고 자료
이제야 git push 지령이 안 들려요. - shoma2da's diary.

example


shell
% git subtree push --prefix=modules/css --squash cssrepo master
git push using:  cssrepo master
-n 1/      22 (0)
-n 2/      22 (1)
-n 3/      22 (2)
-n 4/      22 (3)
-n 5/      22 (4)
-n 6/      22 (5)
-n 7/      22 (6)
-n 8/      22 (7)
-n 9/      22 (8)
-n 10/      22 (9)
-n 11/      22 (10)
-n 12/      22 (11)
-n 13/      22 (12)
-n 14/      22 (13)
-n 15/      22 (14)
-n 16/      22 (15)
-n 17/      22 (16)
-n 18/      22 (17)
-n 19/      22 (18)
-n 20/      22 (19)
-n 21/      22 (19)
-n 22/      22 (20)
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 351 bytes | 0 bytes/s, done.
Total 3 (delta 2), reused 0 (delta 0)
To /Users/hoge/git/tests/css.git
   ca32985..c54cf15  c54cf15de7a448205e4fe4e6991db8ef12270c18 -> master
remote를 통해 업데이트되었음을 확인할 수 있습니다.

subtree pull


이번에는 반대로 외부에서 업데이트된 창고를 풀로 진행해 봅시다.
git subtree pull  --prefix=<prefix> --squash <repository> <refspec...>
<prefix> 캡처할 디렉토리의 이름을 지정합니다.
dd,push와 같습니다.마지막으로 빗장을 넣지 않도록 주의해라.<repository> 외부 창고 명칭.이때는 [cssrepo]입니다.<refspec...> [로컬 분기 이름: 원격 저장소 이름]
콜론을 생략하면 로컬과 원격 모두 같은 지점을 지정합니다.

example


shell
% git subtree pull --prefix=modules/css --squash cssrepo master
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /Users/hoge/git/tests/css
 * branch            master     -> FETCH_HEAD
Auto-merging modules/css/oreore.css
CONFLICT (content): Merge conflict in modules/css/oreore.css
Automatic merge failed; fix conflicts and then commit the result.
로컬subtree의 파일과 원격 파일이 충돌합니다.
사실 여기가 너한테 제일 잘 어울리는 곳이야.
[git subtree]에서 검색하고 히트한 사이트를 보니 어디에서도 충돌이 일어나지 않았다.
근데 이건 절대 충돌 아니에요?
일반적인pull과 달리subtreepull은 내부에서merge분지와 같은 처리를 하고 있지 않습니까?
그러니 충돌을 솔직하게 해소하고 가자.

충돌할 때는 p4merge.


그럼에도 불구하고 충돌하면 "git 무서워!"그렇죠?
충돌은git를 사용할 때 넘어야 하는 벽입니다.
그리고 의외로 벽이 낮을 수도 있어요.
충돌 시 "git mergetool"명령을 입력하면 병합 도구가 시작됩니다.
이렇게 충돌을 없애면 되지만 기본 설정은 뭔지 모를 수도 있다.
따라서 'p4merge' 라는 GUI 프로그램을 가져오면mergetool을 간단하게 사용할 수 있습니다.
관심 있는 사람은 아래 사이트를 참고하세요.
Giit의 diff 도구와 통합 도구(p4merge)Mac를 설정합니다. - 성공하지 않는 것은 사람의 행동입니다.
Git의 분산 개발 관리 16 – p4merge를 사용하여 통합 | Developers.IO
Giit의 통합 도구에서 p4merge를 사용해 보았습니다
충돌 제거% git commit -a 완료.

git alias 추가


그렇기 때문에git subtree add --prefix=<prefix> --squash <repository> <refspec> git subtree push --prefix=<prefix> --squash <repository> <refspec> git subtree pull --prefix=<prefix> --squash <repository> <refspec>이 세 가지 지령을 기억하면subtree는 기본적으로 사용할 수 있다.
근데... 지령이 너무 길죠?귀찮으시죠?
그러니까 별명을 정해.
예를 들어 [git log]를 치는 것이 귀찮다면 아래 명령을 조개껍질에 복사해서 실행하세요.git config --global alias.l log이렇게 별명을 설정하고 [git]를 입력하면 [git log]를 대체할 수 있습니다.
다음에 설정 파일을 직접 편집하세요.홈 디렉토리
[.gitconfig]라는 파일이 있습니다. 열어 보십시오.
~/.gitconfig
[alias]
    l = log
나는 방금 등록한 별명이 있을 것이라고 생각한다.
[l]은 [log]로 해석되는 설정이다.
그럼subtree를 간단하게 사용하기 위해 세 줄의 별명을 추가했습니다.
.gitconfig
[alias]
    l = log
    subadd = "!f () { git subtree add --prefix=${1}  --squash ${2}  ${3} ;};f"
    subpush = "!f () { git subtree push --prefix=${1}  --squash ${2}  ${3} ;};f"
    subpull = "!f () { git subtree pull --prefix=${1}  --squash ${2}  ${3} ;};f"

이렇게 됐어요.

git subtree add --prefix=<prefix> --squash <repository> <refspec>
↓
git subadd <prefix> <repository> <refspec>

git subtree push --prefix=<prefix> --squash <repository> <refspec>
↓
git subpush <prefix> <repository> <refspec>

git subtree pull --prefix=<prefix> --squash <repository> <refspec>
↓
git subpull <prefix> <repository> <refspec>
이렇게 하면 아주 긴 지령을 내릴 필요가 없다.

의문


subtree의 HELP를 보려면 git subtree -h를 입력합니다.
% git subtree -h
usage: git subtree add   --prefix=<prefix> <commit>
   or: git subtree add   --prefix=<prefix> <repository> <ref>
   or: git subtree merge --prefix=<prefix> <commit>
   or: git subtree pull  --prefix=<prefix> <repository> <ref>
   or: git subtree push  --prefix=<prefix> <repository> <ref>
   or: git subtree split --prefix=<prefix> <commit...>

    -h, --help            show the help
    -q                    quiet
    -d                    show debug messages
    -P, --prefix ...      the name of the subdir to split out
    -m, --message ...     use the given message as the commit message for the merge commit

options for 'split'
    --annotate ...        add a prefix to commit message of new commits
    -b, --branch ...      create a new branch from the split subtree
    --ignore-joins        ignore prior --rejoin commits
    --onto ...            try connecting new tree to an existing one
    --rejoin              merge the new branch back into HEAD

options for 'add', 'merge', 'pull' and 'push'
    --squash              merge subtree changes as a single commit
그리고 궁금한 게 있어요.git subtree split은 어떻게 사용하나요?
그리고git subtree pull 시 충돌하지 않는 방법이 존재합니까?

총결산

# 取り込みたい外部モジュールのリポジトリをリモートに登録
git remote add <name> <url>

# 外部モジュールをプロジェクトに取り込む
git subtree add --prefix=<prefix> --squash <repository> <refspec>

# 外部リポジトリにpush(事前にadd,commitが必要)
git subtree push --prefix=<prefix> --squash <repository> <refspec>

# 外部リポジトリの更新をpull
git subtree pull --prefix=<prefix> --squash <repository> <refspec>
git mergetool
git commit -m 'hoge' -a

별칭 설정


.gitconfig
[alias]
    subadd = "!f () { git subtree add --prefix=${1}  --squash ${2}  ${3} ;};f"
    subpush = "!f () { git subtree push --prefix=${1}  --squash ${2}  ${3} ;};f"
    subpull = "!f () { git subtree pull --prefix=${1}  --squash ${2}  ${3} ;};f"

별칭 설정 후 명령

git subadd <prefix> <repository> <refspec>

git subpush <prefix> <repository> <refspec>

git subpull <prefix> <repository> <refspec>


합병을 걱정할 때 기록하는 사람--no-commit 후 생략합니다.

좋은 웹페이지 즐겨찾기