JGIT Simple하게 사용하기

dev-well-being·2023년 1월 2일
2
post-thumbnail

서버에서 파일을 생성하고 GIT에다가 Commit하고 원격 Repo에다가 Push 해야하는 기능이 필요했다. 현재 Backend는 spring-webflux로 개발되어 있으므로 java로 git 기능을 사용할 수 있는 라이브러로를 찾던 중 JGIT이라는 것을 알게 되었다.

JGIT 공식사이트 가기

이클립스를 만든 회사에서 개발한 라이브러리인 듯 하다. 모든 기능을 다 사용해보지는 못했지만 일반적으로 GIT에서 사용하는 기능은 대부분 지원해주는 듯 하다.

아래 내가 써 본 기능을 한번 정리해봤다.

1. init

특정 폴더를 git repo로 생성하는 init 기능을 jgit으로 할 수 있다.

    @Test
    @DisplayName("git init test")
    @Order(1)
    void gitInitTest() throws GitAPIException, IOException {
        //create git folder
        File gitDir = new File("C:\\jgit_test\\git_init_test");
        if(gitDir.exists()){
            FileUtils.deleteDirectory(gitDir);
        }

        if(gitDir.mkdirs()){
            log.info("dir create success");
        }
        //init
        Git git = Git.init().setDirectory(gitDir).call();
        Assertions.assertThat(git).isNotNull();
        git.close();
    }

특정 폴더를 생성하고 Git.init() 메소드에 해당 폴더를 지정하여 호출하면 해당 폴더가 git repo로 잡히고 Git 파일을 생성한다.


임시로 생성한 git_init_test 폴더에 .git 폴더 생성된 것을 확인할 수 있다.

2. clone

GitHub, GitLab 같은 remote repository로부터 local repository를 생성할 수 있는 clone 작업도 할 수 있다.

	@Test
    @DisplayName("git-hub clone test")
    @Order(2)
    void gitHubCloneTest() throws GitAPIException, IOException {
        //create git folder
        File gitDir = new File("C:\\jgit_test\\git_hub_clone_test");
        if(gitDir.exists()){
            FileUtils.deleteDirectory(gitDir);
        }

        if(gitDir.mkdirs()){
            log.info("dir create success");
        }

        //set username, access token
        CredentialsProvider credentialsProvider
                = new UsernamePasswordCredentialsProvider(
                        "ID 입력"
                        , "액세스토큰 입력"); //access token

        //clone
        Git git = Git.cloneRepository()
                .setURI("원격 GIT 주소 URI")
                .setCredentialsProvider(credentialsProvider)
                .setDirectory(gitDir)
                .call();
        Assertions.assertThat(git).isNotNull();
        git.close();
    }

Git.cloneRepository() 메소드를 활용하여 로컬PC에 폴더를 생성하고 해당 폴더에 clone을 한다. CredentialsProvider 객체에 remote git의 ID와 액세스 토큰을 설정한다.

#Git 액세스 토큰을 발급받는 방법은 구글 검색을 하면 많은 자료가 검색된다.


해당 코드를 실행하면 위와 같이 clone 작업이 실행됐음을 알 수 있다.

3. add & commit

git에다 소스를 반영하는 add & commit 아래와 같이 구현 가능하다.

	@Test
    @DisplayName("git add test")
    @Order(4)
    void gitAddTest() throws GitAPIException, IOException {
        //git repo path
        String dirPath = "C:\\jgit_test\\jgit-push-test";
        File gitDir = new File(dirPath);

        //create temp file
        String fileName = UUID.randomUUID().toString();
        File file = new File(dirPath+"\\"+fileName+".txt");
        FileUtils.writeStringToFile(file, "testing it...", StandardCharsets.UTF_8);

        //add
        Git git = Git.open(gitDir);
        Assertions.assertThat(git).isNotNull();

        AddCommand add = git.add();
        add.addFilepattern(fileName+".txt").call();

        git.close();
    }

    @Test
    @DisplayName("git commit test")
    @Order(5)
    void gitCommitTest() throws IOException, GitAPIException {
        //git repo path
        String dirPath = "C:\\jgit_test\\jgit-push-test";
        File gitDir = new File(dirPath);

        //commit
        Git git = Git.open(gitDir);
        git.commit().setMessage("JGIT commit test").call();
        Assertions.assertThat(git).isNotNull();

        git.close();
    }    

git폴더를 Git.open 메소드로 지정한 후 add, commit 사용이 가능하다. git과 똑같이 파일지정하여 add하고 commit시 메세지도 입력 가능하다.

4. push

remote repository에 소스를 반영하는 push 작업도 작업 가능하다.

	@Test
    @DisplayName("git push test")
    @Order(6)
    void gitPushTest() throws IOException, GitAPIException {
        //git repo path
        String dirPath = "C:\\jgit_test\\jgit-push-test";
        File gitDir = new File(dirPath);

        //set username, access token
        CredentialsProvider credentialsProvider
                = new UsernamePasswordCredentialsProvider(
                	"ID 입력"
                    , "액세스토큰 입력"); //access token

        //push
        Git git = Git.open(gitDir);
        git.push()
                .setCredentialsProvider(credentialsProvider)
                .setRemote("원격이름")
                .setRefSpecs(new RefSpec("branch명"))
                .call();
        Assertions.assertThat(git).isNotNull();

        git.close();
    }

원격 이름과 branch를 지정하고 실행하면 push가 된다.

5. branch & merge

우리가 git 사용하는 이유의 8할은 branch 기능이 넘 잘 되어 있기 때문이다. 우리는 기존 소스에서 영향도가 큰 작업을 할 경우 branch를 생성해서 해당 branch에서 작업을 진행하게 된다.

	@Test
    @DisplayName("git branch merge test")
    @Order(7)
    void gitBranchMergeTest() throws IOException, GitAPIException {
        //git repo path
        String dirPath = "C:\\jgit_test\\jgit-push-test";
        File gitDir = new File(dirPath);

        //set username, access token
        CredentialsProvider credentialsProvider
                = new UsernamePasswordCredentialsProvider(
                	"ID 입력"
                    , "액세스토큰 입력"); //access token

        //branch create
        Git git = Git.open(gitDir);
        String branchName = "새로 생성할 branch명";
        List<Ref> branchList =
        				git
        				.branchList()
        				.setListMode(ListBranchCommand.ListMode.ALL)
                        .call();
                        
        //기존 branch가 존재하는지 여부 체크
        boolean existYn = branchList
        				.stream()
        				.anyMatch(ref ->
                        		ref.getName()
                                .endsWith("heads/"+branchName));
        
        //branch가 없을 경우 branch를 생성한다.
        if(!existYn){
            git.branchCreate().setName(branchName).call();
        }

        //merge sub into main
        git.checkout().setName(branchName).call();
        ObjectId mergeBase = git.getRepository().resolve("merge 대상 branch명");
        MergeResult merge = git.merge()
                        .include(mergeBase)
                        .setCommit(true)
                        .setFastForward(MergeCommand.FastForwardMode.NO_FF)
                        .setMessage("Merged changes")
                        .call();

        Assertions.assertThat(merge.getMergeStatus().isSuccessful()).isTrue();

        //push
        if(merge.getMergeStatus().isSuccessful()){
            git.push()
                    .setCredentialsProvider(credentialsProvider)
                    .setRemote("원격이름")
                    .setRefSpecs(new RefSpec(branchName))
                    .call();
            Assertions.assertThat(git).isNotNull();

            git.close();
        }
    }

위 소스는 sub라는 임의 branch를 생성하여 기존 작업 branch 내역을 merge한다. 그리고 remote git에도 해당 branch를 push 한다.

JGIT을 통해 ADD -> Commit -> Push -> branch create -> merge가 정상적으로 수행됐는지 아래처럼 확인했다.

profile
안녕하세요!! 좋은 개발 문화를 위해 노력하는 dev-well-being 입니다.

0개의 댓글