다른 브랜치의 특정 git commit을 현재 브랜치에 적용하고 싶을 때가 있다.

만약 그 commit을 그대로 적용하는 경우는 `git cherry-pick`을 사용하면 된다.

그러나 commit까지는 적용하지 않고, 단순히 patch 형태로 적용하기 위해서는 아래처럼 하면 된다.

참고로 git cherry-pick --no-commit도 이용할 수 있으나, 이것은 수정 사항이 git add까지 적용되어 불편하다. 

 

내 경우에는 빌드 스크립트 중에 특정 commit을 임시적인 patch 형태로 적용하는 경우에 주로 사용한다.

git show <commit> | patch -p1

이 글에서는 'repo manifests' 명령에 대한 내용을 서술한다.

 

개요

업무시에 일정한 시점 사이동안 변경된 commit을 확인이 필요한 경우가 있다.

이 경우에는 두 시점의 manifest 파일을 생성하고, 이 둘 사이의 commit을 비교하면 된다.

회사에서 이러한 용도를 위해 작성된 Linux Shell Script를 사용하고 있는데, 조금 아쉽기는 했다.

다른 유틸리티를 찾다보니, repo 명령어에도 이러한 기능을 제공하는 명령어가 있었다.

 

$ repo help diffmanifests

Summary

Manifest diff utility

Usage: repo diffmanifests manifest1.xml [manifest2.xml] [options]

Options:
  -h, --help            show this help message and exit
  --raw                 Display raw diff.
  --no-color            does not display the diff in color.
  --pretty-format=<FORMAT>
                        print the log using a custom git pretty format string

Description

The repo diffmanifests command shows differences between project
revisions of manifest1 and manifest2. if manifest2 is not specified,
current manifest.xml will be used instead. Both absolute and relative
paths may be used for manifests. Relative paths start from project's
".repo/manifests" folder.

The --raw option Displays the diff in a way that facilitates parsing,
the project pattern will be <status> <path> <revision from> [<revision
to>] and the commit pattern will be <status> <onelined log> with status
values respectively :

  A = Added project
  R = Removed project
  C = Changed project
  U = Project with unreachable revision(s) (revision(s) not found)

for project, and

   A = Added commit
   R = Removed commit

for a commit.

Only changed projects may contain commits, and commit status always
starts with a space, and are part of last printed project. Unreachable
revisions may occur if project is not up to date or if repo has not been
initialized with all the groups, in which case some projects won't be
synced and their revisions won't be found.

 

사용법은 단순히 'repo diffmanifests <manifest 1> <manifest 2> <option>'을 사용하면 된다.

이 명령을 실행하면, <manifest 1>기준으로 <manifest 2>와의 변경된 commit을 보여준다.

만약 <manifest 2>를 생략하면, manifest.xml으로 대체된다. 즉, 현재 사용중인 maniefst와 비교한다.

 

실행화면

다음은 실제 실행 화면이다.

added projects는 두번째 manifest 파일에서 추가된 저장소이며,

changed projects는 변경된 저장소와 commit을 표시한다.

그런데, 나는 commit의 작성자 정보도 잘 사용하는 편이기 때문에, '--pretty-format' 옵션으로 작성자 정보도 추가해보았다.

 

 

기능 변경

그런데, diffmanifests 명령의 기준이 저장소 이름 (name)이 아니라 저장소 경로 (path)이다.

해당 코드를 살펴보면, 저장소 경로를 기준으로 정렬한 이후에 해당 저장소의 commit을 보여준다.

저장소 경로는 저장소의 unique한 식별자가 아니기 때문에, 나는 저장소 이름 기준으로 표시하도록 수정하였다.

 

관련된 코드 경로는 다음과 같다.

  • .repo/repo/manifest_xml.py
  • .repo/repo/subcmds/diffmanifests.py
$ git diff
diff --git a/subcmds/diffmanifests.py b/subcmds/diffmanifests.py
index b999699..f2269d3 100644
--- a/subcmds/diffmanifests.py
+++ b/subcmds/diffmanifests.py
@@ -79,21 +79,21 @@ synced and their revisions won't be found.

   def _printRawDiff(self, diff):
     for project in diff['added']:
-      self.printText("A %s %s" % (project.relpath, project.revisionExpr))
+      self.printText("A %s %s" % (project.name, project.revisionExpr))
       self.out.nl()

     for project in diff['removed']:
-      self.printText("R %s %s" % (project.relpath, project.revisionExpr))
+      self.printText("R %s %s" % (project.name, project.revisionExpr))
       self.out.nl()

     for project, otherProject in diff['changed']:
-      self.printText("C %s %s %s" % (project.relpath, project.revisionExpr,
+      self.printText("C %s %s %s" % (project.name, project.revisionExpr,
                                      otherProject.revisionExpr))
       self.out.nl()
       self._printLogs(project, otherProject, raw=True, color=False)

     for project, otherProject in diff['unreachable']:
-      self.printText("U %s %s %s" % (project.relpath, project.revisionExpr,
+      self.printText("U %s %s %s" % (project.name, project.revisionExpr,
                                      otherProject.revisionExpr))
       self.out.nl()

@@ -103,7 +103,7 @@ synced and their revisions won't be found.
       self.printText('added projects : \n')
       self.out.nl()
       for project in diff['added']:
-        self.printProject('\t%s' % (project.relpath))
+        self.printProject('\t%s' % (project.name))
         self.printText(' at revision ')
         self.printRevision(project.revisionExpr)
         self.out.nl()
@@ -113,7 +113,7 @@ synced and their revisions won't be found.
       self.printText('removed projects : \n')
       self.out.nl()
       for project in diff['removed']:
-        self.printProject('\t%s' % (project.relpath))
+        self.printProject('\t%s' % (project.name))
         self.printText(' at revision ')
         self.printRevision(project.revisionExpr)
         self.out.nl()
@@ -123,7 +123,7 @@ synced and their revisions won't be found.
       self.printText('changed projects : \n')
       self.out.nl()
       for project, otherProject in diff['changed']:
-        self.printProject('\t%s' % (project.relpath))
+        self.printProject('\t%s' % (project.name))
         self.printText(' changed from ')
         self.printRevision(project.revisionExpr)
         self.printText(' to ')
@@ -138,7 +138,7 @@ synced and their revisions won't be found.
       self.printText('projects with unreachable revisions : \n')
       self.out.nl()
       for project, otherProject in diff['unreachable']:
-        self.printProject('\t%s ' % (project.relpath))
+        self.printProject('\t%s ' % (project.name))
         self.printRevision(project.revisionExpr)
         self.printText(' or ')
         self.printRevision(otherProject.revisionExpr)

 

수정된 사항을 내용을 적용하여 다시 'repo manifests' 명령을 실행하였다.

vendor/....  경로로 표시되던 저장소가 projects/... 이름으로 표시됨을 알 수 있다.

 

이번 글에서는 Gerrit 3.1.10에서 Gerrit 3.5.1로의 이전에 관한 내용을 서술한다.

 

참고글은 다음과 같다

Gerrit 3.1.10 - 이전 설치 ( Migration, Docker )에서 작성한 내용과 아주 유사하다.

 

설치 준비

mkdir gerrit_3.5.1 && cd gerrit_3.5.1
touch docker-compose.yml

mkdir gerrit
cp -r $SRC/gerrit/cache gerrit
cp -r $SRC/gerrit/db gerrit
cp -r $SRC/gerrit/etc gerrit
cp -r $SRC/gerrit/git gerrit
cp -r $SRC/gerrit/index gerrit

mkdir httpd
cp $SRC/httpd/httpd.conf httpd   # 설정파일, 원래 장소에서 복사
cp $SRC/httpd/.htpasswd httpd    # 계정과 암호파일, 원래 장소에서 복사

노트:

  • plugins은 3.5.1용으로 설치하기 위해서 기존 백업데이터를 이용하지 않았다. 

 

file: docker-compose.yml

version: '3'

services:
  gerrit:
    image: gerritcodereview/gerrit:3.5.1-ubuntu20
    user: root
    ports:
      - "29418:29418"
    volumes:
      - ./gerrit/db:/var/gerrit/db
      - ./gerrit/etc:/var/gerrit/etc
      - ./gerrit/git:/var/gerrit/git
      - ./gerrit/index:/var/gerrit/index
    environment:
      - CANONICAL_WEB_URL=http://localhost:8100
    command: init

  apache:
    image: httpd
    volumes:
      - ./httpd/httpd.conf:/usr/local/apache2/conf/httpd.conf
      - ./httpd/.htpasswd:/usr/local/apache2/conf/.htpasswd
    ports:
       - "8100:80"

노트:

  • plugins은 3.5.1용으로 설치하기 위해서 기존 백업데이터를 이용하지 않았다. 즉, volumes 항목에서 제외하였다.
  • command: init 부분이 아주 중요하다. 이 부분이 없으면, 백업한 자료들을 모두 초기화한다. 기존 자료를 이용하여 초기화 하기 위해서는 주석을 풀고, 실행해주어야 한다. (1회성) 

 

file: gerrit/etc/gerrit.config

[gerrit]
        basePath = git
        canonicalWebUrl = http://localhost:8100/
        serverId = 5618f8c1-7707-41a7-be27-c2f23aa6790c
[index]
        type = lucene
[auth]
        type = http
        logoutUrl = http://aa:aa@localhost:8100/login
        trustContainerAuth = true  # remote로 plugin 설치위해
[receive]
        enableSignedPush = false
[sendemail]
        enable = true
        smtpServer = smtprelay.MYCOMPANY.COM
        smtpServerPort = 25
        smtpUser = SMTPUSER
        smtpPass = SMPTPASS
[user]
        email = no_reply@MYCOMPANY.COM
        anonymousCoward = COMPANY Gerrit
[sshd]
        listenAddress = *:29418
[httpd]
        listenUrl = http://*:8080/
[cache]
        directory = cache
[commentLink "its-jira"]
        match = \\[([A-Z]+-[0-9]+)\\]
        html = <a href=\"https://jira.MYCOMPANY.COM/browse/$1\">[$1]</a>
        association = SUGGESTED
[its-jira]
        url = https://jira.MYCOMPANY
        username = JIRA-USER
        password = JIRA-PASS
[plugins]
        allowRemoteAdmin = true

 

file: gerrit/etc/its/actions.config

[rule "merged"]
    event-type = change-merged
    action = add-standard-comment

 

file: httpd/httpd.conf

...
LoadModule proxy_module modules/mod_proxy.so  # 주석제거
...
LoadModule proxy_http_module modules/mod_proxy_http.so # 주석제거
...

# 파일끝에 아래 추가
<IfModule ssl_module>
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
</IfModule>
<VirtualHost *>
    ServerName gerrit
    ProxyRequests Off
    ProxyVia Off
    ProxyPreserveHost On

    <Proxy *>
        Order deny,allow
        Allow from all
    </Proxy>
<Location "/">
AuthType Basic
AuthName "Gerrit Code Review"
AuthBasicProvider file
AuthUserFile '/usr/local/apache2/conf/.htpasswd'
Require valid-user
</Location>
AllowEncodedSlashes On
ProxyPass / http://gerrit:8080/ nocanon
</VirtualHost>

 

 

설치 실행

먼저 docker-compose.yml의 command 부분 주석을 제거하고 Gerrit의 초기화를 실행한다.

docker-compose up gerrit

Gerrit 3.1.10 초기화때와는 다르게, 초기화가 완료되면 자동 종료된다.

 

gerrit_1  | [2022-05-17 09:59:26,479] [main] INFO  com.google.gerrit.server.plugins.PluginLoader : Unloading plugin replication, version v3.5.1
gerrit_1  | [2022-05-17 09:59:26,480] [main] INFO  com.google.gerrit.server.plugins.PluginLoader : Unloading plugin codemirror-editor, version v3.5.1
gerrit_1  | [2022-05-17 09:59:26,481] [main] INFO  com.google.gerrit.server.plugins.PluginLoader : Unloading plugin gitiles, version v3.5.1
gerrit_1  | [2022-05-17 09:59:26,481] [main] INFO  com.google.gerrit.server.plugins.PluginLoader : Unloading plugin reviewnotes, version v3.5.1
gerrit_1  | [2022-05-17 09:59:26,482] [main] INFO  com.google.gerrit.server.plugins.PluginLoader : Unloading plugin download-commands, version v3.5.1
gerrit_1  | [2022-05-17 09:59:26,482] [main] INFO  com.google.gerrit.server.plugins.PluginLoader : Unloading plugin commit-message-length-validator, version v3.5.1
gerrit_1  | [2022-05-17 09:59:26,483] [main] INFO  com.google.gerrit.server.plugins.PluginLoader : Unloading plugin webhooks, version v3.5.1
gerrit_1  | [2022-05-17 09:59:26,483] [main] INFO  com.google.gerrit.server.plugins.PluginLoader : Unloading plugin avatars-gravatar, version 4d45f66597
gerrit_1  | [2022-05-17 09:59:26,483] [main] INFO  com.google.gerrit.server.plugins.PluginLoader : Unloading plugin delete-project, version v3.5.1
gerrit_1  | [2022-05-17 09:59:26,484] [main] INFO  com.google.gerrit.server.plugins.PluginLoader : Unloading plugin plugin-manager, version v3.5.1
gerrit_1  | [2022-05-17 09:59:26,484] [main] INFO  com.google.gerrit.server.plugins.PluginLoader : Unloading plugin singleusergroup, version v3.5.1
gerrit_1  | [2022-05-17 09:59:26,484] [main] INFO  com.google.gerrit.server.plugins.PluginLoader : Unloading plugin hooks, version v3.5.1
gerrit_1  | [2022-05-17 09:59:26,484] [main] INFO  com.google.gerrit.server.plugins.PluginLoader : Unloading plugin uploadvalidator, version v3.0.0-rc1-284-gefecf8cdf4
gerrit_1  | [2022-05-17 09:59:26,578] [main] INFO  com.google.gerrit.server.plugins.CleanupHandle : Cleaned plugin plugin_replication_220517_0958_9713708846942515415.jar
gerrit_1  | [2022-05-17 09:59:26,579] [main] INFO  com.google.gerrit.server.plugins.CleanupHandle : Cleaned plugin plugin_codemirror-editor_220517_0958_2369289632520411003.jar
gerrit_1  | [2022-05-17 09:59:26,579] [main] INFO  com.google.gerrit.server.plugins.CleanupHandle : Cleaned plugin plugin_gitiles_220517_0958_14918039203576338770.jar
gerrit_1  | [2022-05-17 09:59:26,579] [main] INFO  com.google.gerrit.server.plugins.CleanupHandle : Cleaned plugin plugin_reviewnotes_220517_0958_5216294365523276074.jar
gerrit_1  | [2022-05-17 09:59:26,579] [main] INFO  com.google.gerrit.server.plugins.CleanupHandle : Cleaned plugin plugin_download-commands_220517_0958_4264228789875070900.jar
gerrit_1  | [2022-05-17 09:59:26,580] [main] INFO  com.google.gerrit.server.plugins.CleanupHandle : Cleaned plugin plugin_commit-message-length-validator_220517_0958_13705660632656731886.jar
gerrit_1  | [2022-05-17 09:59:26,580] [main] INFO  com.google.gerrit.server.plugins.CleanupHandle : Cleaned plugin plugin_webhooks_220517_0958_13317217803860358281.jar
gerrit_1  | [2022-05-17 09:59:26,580] [main] INFO  com.google.gerrit.server.plugins.CleanupHandle : Cleaned plugin plugin_avatars-gravatar_220517_0958_8896828478575643447.jar
gerrit_1  | [2022-05-17 09:59:26,580] [main] INFO  com.google.gerrit.server.plugins.CleanupHandle : Cleaned plugin plugin_delete-project_220517_0958_10873195147850721930.jar
gerrit_1  | [2022-05-17 09:59:26,580] [main] INFO  com.google.gerrit.server.plugins.CleanupHandle : Cleaned plugin plugin_plugin-manager_220517_0958_1093134940356759420.jar
gerrit_1  | [2022-05-17 09:59:26,580] [main] INFO  com.google.gerrit.server.plugins.CleanupHandle : Cleaned plugin plugin_singleusergroup_220517_0958_9729983710349567030.jar
gerrit_1  | [2022-05-17 09:59:26,580] [main] INFO  com.google.gerrit.server.plugins.CleanupHandle : Cleaned plugin plugin_hooks_220517_0958_4063223096168124260.jar
gerrit_1  | [2022-05-17 09:59:26,580] [main] INFO  com.google.gerrit.server.plugins.CleanupHandle : Cleaned plugin plugin_uploadvalidator_220517_0958_16440575924884005494.jar
gerrit_351_gerrit_1 exited with code 0

 

이후에 다시 docker-compose.yml의 command 부분을 주석처리하고 다시 Gerrit 및 httpd 서비스를 실행한다.

docker-compose up

 

이후에 Gerrit을 실행하면, 정상적으로 동작함을 확인할 수 있다.

플러그인 설치를 위해 Install plugins을 클릭하고, its-base와 its-jira를 설치해주었다. ( Jira와 Link 및 comment 추가를 위해 )

 

기존 이력도 확인할 수 있고, 좌측아래에서 버전이 3.5.1 임을 확인할 수 있다.

 

Gerrit와 Jira의 연계 테스트를 위해서 하나의 commit을 merge했더니, Jira에 comment가 잘 추가되었다.

 

 

 

'Gerrit' 카테고리의 다른 글

Gerrit 3.1.10 - 이전 설치 ( Migration, Docker )  (0) 2022.05.16
Gerrit 3.5.1 - 설치 ( Docker )  (0) 2022.05.11
Gerrit - LDAP 설정  (0) 2022.05.03
Gerrit - 설치 ( Standalone )  (0) 2022.04.22
Gerrit - 설치 ( Quickstart )  (0) 2022.04.20

+ Recent posts