Fast Forword와 merge 그리고 rebase 정리

IT 지식/Git|2019. 12. 13. 00:01

5년차가 될정도로 개발을 어느정도 진행했지만 아직까지도 git에 대한 정리가 잘 되지 않는다.

 

공부도 하고 정리도 했었지만 실상 회사에서 주구장창 브랜치 만들고 머지만 해서 진행했기 때문에 fast forword를 하고 merge, rebase하는 것과 안하고 하는것의 방법을 잘 알지 못했다.

 

개념은 알아도 직접 많이 해보지 않으면 그게 와닿지 않는 것 같다.

그럼 현재 이직한 회사에서는 이 방법을 많이 사용하기에 정리를 해서 까먹지 않도록 해보자.

 

Merge

Merge는 이미 우리가 익히 알고 있듯이 두 개의 브랜치를 합치는 걸 의미한다. 그럼 fast forword를 하고 merge를 하면 어떻게 되는지 보자.

현재 이렇게 되어있는 상황에서 feature/si를 fast forword 포함해서 merge 해보겠다.  우선 master로 checkout하고 머지하려고 하는 feature/test 브랜치 우측클릭하여 머지를 해보자.

그럼 master가 feature/si의 커밋 위치로 가있는 것을 알 수 있다.

그럼 다시 마스터를 커밋하기 전으로 돌리고 다시 non fast forword를 해보자.

우선 다시 돌리자.

그리고 source tree에서는 global옵션 - Git에서 "병합 시 fast-forword를 사용하지 않고 항상 커밋을 생성"을 선택하고 다시 merge 해보자.

그러면 아래와 같은 모양으로 feature/si의 브랜치는 그대로 있고 master의 브랜치는 더 앞으로 가있는 것을 볼 수 있다.

 

그럼 과연 fast forword가 정확히 무엇인가?? 

궁금하다.

 

찾아보니 fast forword는 병합하려는 브랜치에 새로운 커밋이 없는 상황에서 발생되며 merge가 된 브랜치의 최신 커밋으로 head가 옮겨지는 것을 말한다.

 

위의 예에서 보면 master에서 분기된 feature/si브랜치가 새로운 커밋을 가지고 있고 master는 feature/si가 분기 된 이후에 새로운 커밋이 없는 상황이었다. 이때 git merge feature/si를 하게 되면 master는 feature/si 마지막 커밋으로 옮겨지고 한줄로 이어서 보여지는 아래 그림 오른쪽 처럼 되게 된다. 

 

하지만 이는 이력관리하기가 어렵기 때문에 merge하는것처럼 보여주고 이력관리를 위해서 --no-ff 옵션을 붙여서 머지하게 되면 왼쪽처럼 히스토리도 남고 master와 breanch의 위치가 구분되게 된다.

Rebase

rebase는 feature 브랜치의 커밋을 새로 rebase되는 커밋의 parent commit으로 된다. 이렇게 하게 되면 히스토리가 깔끔하게 보인다.

우선 rebase를 진행하기 위해 feature 브랜치로 checkout하고 rebase를 진행할 마스터 브랜치를 누르고 리베이스를 진행한다.

그럼 아래처럼 master위에 feature 브랜치가 위로 붙는 구조가 될것이다.  

이 상태에서 마스터로 체크아웃 하고 feature/si로 merge를 하면 fast forword가 되어 둘이 동일한 커밋을 바라보게 된다.

명령어로 정리하면 다음과 같다.

git checkout feature/si
git rebase master
git checkout master
git merge feature/si

 

 

하지만 이렇게 되면 브랜치의 히스토리를 확인하기가 어렵다. 만약 히스토리를 확인하고 싶으면 아래 명령어를 사용하면 히스토리를 확인할 수 있다.

git checkout feature/si
git rebase master
git checkout master
git merge --no-ff feature/si

 

 

어렵다 ㅋㅋ git은 해도해도 헷갈린다. 

만약 참고하시고 이상한 부분 있으면 말씀 부탁드립니다~

댓글()

[토이 프로젝트 소개] 개발자 채용, 기술 블로그 정보를 모아주는 TimeLine

IT 지식/기타지식|2019. 8. 18. 21:46

혼자 공부를 집에서 어떻게 하면 효율적일까 고민을 많이했다.

집에서 주구장창 책을 읽고 해보면 스킬이 늘까? 그렇게 해봤지만 그게 정답은 아니었다. 남들에게는 모르겠으나 나에게는 아니었다. 

 

회사에서 하는 업무는 한정적이니 내가 회사에서 하지 못하지만 알고 싶고 잊고 싶지 않은 내용에 대해서 프로그램을 직접 만들면서 공부할 내용을 정리하고 싶었다.

그래서 만들게 된게 타임라인인데, 개발자 채용정보나 기술 블로그를 rss등을 사용해서 모아볼 수는 있으나 별도의 관리 툴이나 브라우저에서 확인해야해서 좀 불편했다. 그래서 그것을 한번에 볼수 있게 하는 사이트가 있으면 좋을 것 같아서 만들어봤다.

우선 주소는 http://wedul.space이다. aws에 도입하고 싶었으나 비용도 걱정되니해서 집에있는 간이 서버에 도입하였다.

화면은 잘 그릴지 몰라서 vue.js 책을 사서 간단하게 읽고 구성했다.

 

홈 / JOB / TECH로 페이지는 구성되어 있고 앞으로 로그인하여 본인이 구독하고 싶은 회사만 보는 기능을 추가할 예정이다. 그리고 자세히보기 누르면 현재는 해당 페이지로 이동하지만 timeline 내부에서 볼 수 있는 페이지를 추가할 예정이다.

 

원래는 혼자 저 정도 까지 구성하다가 크롤링 사이트를 확장하는데 혼자하기에는 조금 역부족이고 함께하고 하고자 하는 친구가 있어서 요청했다. 그래서 테크쪽과 프론트는 그 친구가 담당해주고 있다. 

저장소는 공개 되어있고 참여하고 싶으신 분들은 pull-request 보내주셔도 좋다.

https://github.com/weggdul/timeline

 

 

백엔드 구성


아무래도 나는 백엔드 개발자이다 보니 백엔드에만 사실 집중했다. 크롤링 양이 많지 않아서 별도 배치를 만들거나 큐에 쌓거나 할 필요는 없었으나 공부를 위해서 모두 구성해봤다.

우선 java8, spring-boot2.1.5로 구성되어 있고 멀티모듈로 관리하고 있다. (https://github.com/weggdul/timeline)

api 서버는 spring-batch를 통해 긁어온 데이터가 쌓여있는 mariadb에서 정보를 가져와 보여주며 중간에 redis가 위치해 있어 데이터를 캐시하고 있다.

 

batch 서버는 spring-batch에서 하루 두번 모든 JOB, tech사이트에 들러 크롤링해오고 그 정보를 kafka로 전송한다. kafka를 리스닝 하고 있다가 kafka에 데이터가 들어오면 읽어서 mariadb로 적재시키고 있다.

 

아직 미완 단계지만 다 만들어지고 나면 배포 자동 구성도 하고 seo도 달고 광고도 한번 달아봐야겠다.

공부도 확실히 되는거 같고.. 연말까지는 하고자 했던거 다 붙여보자.

댓글()
  1. 지나가는개발자 2019.08.19 14:19 댓글주소  수정/삭제  댓글쓰기

    토이프로젝트 깃 주소도 그렇고 서비스주소도 없다고뜨네요?

    • Favicon of https://wedul.site BlogIcon 위들 wedul 2019.08.19 14:26 신고 댓글주소  수정/삭제

      안녕하세요. 주소 정보는 아래와 같구요. 다시한번 확인해주세요!

      서비스 사이트 : http://wedul.space
      github : https://github.com/weggdul/timeline

  2. Favicon of https://wedul.site BlogIcon 위들 wedul 2019.10.30 15:01 신고 댓글주소  수정/삭제  댓글쓰기

    잠시 서비스 중단합니다.

  3. 나그네 2020.01.30 14:19 댓글주소  수정/삭제  댓글쓰기

    작업하시는데 얼마나 걸리셧나요

Github repository 위치 변경

IT 지식/Git|2019. 8. 1. 23:16

github에서 개인적으로 하고 있는 토이프로젝트 wedul_timeline을 친구와 함께 작업하기로 해서 그룹을 생성했다.

그룹 이름은 우리의 아이덴티티에 맞는 potato로 지정했다. ㅋㅋ

 

그런데 이렇게 지정하다보니 기존에 내 repository에 위치해있던 소스를 그룹으로 옮겨야 했다. 

그 과정에서 삽질했던 내용을 다음에는 삽질 하지 않도록 기록해봤다. 

 

현재 Git Repository 저장소 clone

우선 현재 있는 repository를 복사 해야한다.

git clone --mirror https://github.com/weduls/wedul_timeline

복사가 완료되었다. 그럼 이제 새로 이전할 레포지토리가 필요하다.

그룹에 들어가서새로운 레포지토리를 생성한다.

 

새로운 remote origin 설정

변경을 진행할 새로운 remote origin을 설정해준다. 새로운 remote 주소는 당연히 새로 생성한 레포지토리여야 한다.

git remote set-url --push origin https://github.com/weggdul/timeline_m

 

새로운 레포지토리에 복사한 저장소 내역 push

그럼 마지막으로 아까전에 mirror를 진행한 내역을 push로 서버에 밀어 넣어주자.

git push --mirror

 

결과를 확인해보면 레포지토리가 히스토리까지 그대로 옮겨진 것을 확인할 수 있다.

흠 편한군 ㅋㅋ

댓글()
  1. 2019.08.02 10:24 댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

Intellij에서 spring boot multi module 사용시 jsp 못찾는 이슈 해결방법

web/Spring|2019. 4. 10. 23:34

기존에 공부삼아서 개발중이던 wedulpos에 spring batch를 추가해보려고 했다.

그래서 공통으로 mono 프로젝트로 되어있던 wedulpos를 multi module로 수정했다.

 

그랬더니 이상하게 servlet context에서 jsp를 로드하지 못했다.

그래서 계속해서 ServletException not include... jsp 또는 ServletException not jsp found 오류가 발생했다.

 

그래서 엄청난 구글링을 2틀동안했다. 집에서 그리고 약속장소에서 기다리면서 노트북으로 그리고 퇴근하고 오늘..

정말 가지가지한 방법을 다해봤었다. 기본적으로 embed-tomcat의 경우 jasper를 가지고 있지 못해서 별도의 모듈을 추가하고 servlet jspl 추가했고, compileOnly, provieded 별 난리를 다했다 ㅋㅋㅋ

하지만 tiles, url resolver 모두 bean이 등록되어있고 잘 동작하는데 jsp를 못찾는 해결하지 못했다.

최후에 방법으로 검색해본 키워드 intellij에서 정답을 찾았다. 

 

intellij에서 module 안에 웹 모듈을 실행시킬때는 working directory를 해당 모듈로 설정해줘야 한다. 그렇지 않으면 최상의 root로 working directory가 지정되기 때문이다.

https://stackoverflow.com/questions/44794588/intellij-run-configuration-spring-boot-vs-maven-issues

그래서 이 글을 보고 바로 지정해봤다.

 

결과는 성공 ㅋㅋㅋㅋㅋㅋㅋ

 

ㅋㅋㅋㅋ

너무 행복하다.  이 맛에 구글링하고 개발하는거 같다.

 

이제 내일부터는 spring batch를 공부해서 하나하나 정리하고 간단하게 batch를 만들어보자. 휴

git 주소 : https://github.com/weduls/wedulpos_boot

댓글()
  1. 김병관 2019.08.06 09:00 댓글주소  수정/삭제  댓글쓰기

    이 글을 보고 암이 나았습니다.감사합니다.하마터면죽을뻔했네요

  2. 야스오 2019.11.11 13:48 댓글주소  수정/삭제  댓글쓰기

    감사합니다. 덕분에 찾았어요. 이클립스에서 인텔리J로 넘어가기 힘드네요 ~

git ssh로 받은 프로젝트를 https 방식으로 변경하기.

IT 지식/Git|2019. 3. 20. 21:19

회사에서 ssh 방식으로 git을 사용하고 있었으나 정책상 ssh가 막혀서 https로 전환해야 했다.


근데 사실 ssh로만 주로 사용했지 이를 바꿔서 진행해본적이 없어서 난감했다.(기존에 작업중이던거 어떻게 ...)


그래서 알아보던중 같은팀 개발자분이 힌트를 주셔서 그대로 해보니 해결되었다. ㅋㅋ


간단하게 정리해보자.


- 프로젝트 내에 .git의 config파일 열어서 수정

터미널을 이용하든 편집기를 이용해서 config파일을 열어본다.

그럼 밑줄 친 부분과 같이 ssh주소로 되어있는데 이를 repository의 https 주소로 바꿔주고 저장한다.


그리고 다시한번 git 명령어를 시도해보면 다음과 같이 계정 정보를 입력하라고 나오는데 이곳에는 해당 레포지토리가 있는 github이나 gitlab의 계정정보를 입력하면된다.


그럼 끝!

아주 간단하다.


댓글()
  1. 지지리 2019.08.04 21:44 댓글주소  수정/삭제  댓글쓰기

    좋은 정보네요

ngrinder Mac os 간단 설치 및 테스트 방법

IT 지식/ngrinder|2019. 3. 11. 20:55

api의 성능 테스트를 위해서 네이버에서 만든 ngrinder 설치하고 테스트를 진행해봤다.


ngrinder는 controller와 agent로 구성이 되어 있는데 이에 대한 내용은 https://naver.github.io/ngrinder/ 해당 내용을 체크하자.


1. Controller 설치
- 톰캣을 설치하고 아래 주소에서 war를 다운받아서 실행시킨다.
https://github.com/naver/ngrinder/releases
단, 3.4.2는 테스트 스크립트 실행 시 unexpected token에러가 발생한다. 그래서 3.4.1을 사용하는걸 추천한다.

설치 완료되면 아래 url로 접근 해서 확인 (초기 계정은 admin/admin)
- 뒤에 root path는 편의를 위해서 war 파일을 ngrinder-controller-3.4.1.war => ngrinder.war로 변경해서 ngrinder로 사용

http://localhost:8080/ngrinder

 

2. Agent 설치
Agent는 테스트에서 필요한 worker process를 실행시켜주고 관리하는 역할을 한다.
- agent를 다운받고 내부에 ./run_agent.sh를 실행시킨다.

- 실행이 완료되면 Agent Management에 들어가면 정상적으로 동작하는걸 확인할 수 있다.

주의사항
먼저 자바 1.9이상의 버전에서는 Agent을 지원을 하지 않는다. 1.9에서 agent 실행 시 다음과 같은 오류가 난다.

1
java.lang.ClassCastException: class jdk.internal.loader.ClassLoaders$AppClassLoader cannot be cast to class java.net.URLClassLoader (jdk.internal.loader.ClassLoaders$AppClassLoader and java.net.URLClassLoader are in module java.base of loader 'bootstrap')
cs
이는 1.9에서 URLClassLoader를 사용하는 방식이 바뀌었으나 ngrinder agent가 아직 지원하지 못해서 발생하는 오류인거 같다. 1.8을 사용하면 괜찮다.



테스트 진행

각 옵션을 설정하고 테스트를 진행하면 아래와 같이 TPS결과가 나온다. 각 설정 옵션에 대해서는 인터넷이나 메인 git에 가면 자세히 나와있다.


Agent, VUser를 조절해가면서 api의 성능을 tps를 확인하면서 조절해서 테스트하면 된다.



'IT 지식 > ngrinder' 카테고리의 다른 글

ngrinder Mac os 간단 설치 및 테스트 방법  (0) 2019.03.11

댓글()

Facebook Javascript plugin과 spring security를 이용한 페이스북 로그인

web/Spring|2018. 10. 4. 00:57

개인적으로 공부겸 만들고 있는 Wedul Pos에는 아이디와 패스워드를 사용해서 로그인하는 방식을 제공했다.

하지만 페이스북 로그인 방식을 추가해보고 싶어서 facebook 개발자 사이트에 가입하여 정보를 얻고 추가해봤다.

우선 페이스북 로그인 방식을 처리하는 방식은  Facebook Javascript plugin을 사용하여 spring security에서 인증을 하는 방식과 /sign/facebook 요청만 front에서 보내면 server에서 모든 처리를 진행하는 방식 두가지가 있다.

그 중에 첫번째 javascript plugin을 이용하는 방식을 사용해서 구현해보자.

1. facebook developer 사이트에서 javascript 내용 얻기
https://developers.facebook.com/docs/facebook-login/web#confirm 페이지에서 자바스크립트 플러그인에 대한 사용법과 소스를 받을 수 있다. App Id의 경우에는 개발자 사이트에 등록하면 받을 수 있다.

몇 가지 부분만 간단하게 설명을해보자.

※초기화
Facebook javascript 플러그인 사용을 위한 초기화.
{your-app-id}에는 발급받은 App Id를 version에는 최신 버전을 쓰면 된다. 지금은 v3.1이 최신이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
  window.fbAsyncInit = function() {
    FB.init({
      appId      : '{your-app-id}',
      cookie     : true,  // enable cookies to allow the server to access 
                          // the session
      xfbml      : true,  // parse social plugins on this page
      version    : 'v2.8' // use graph api version 2.8
    });
 
    // Now that we've initialized the JavaScript SDK, we call 
    // FB.getLoginStatus().  This function gets the state of the
    // person visiting this page and can return one of three states to
    // the callback you provide.  They can be:
    //
    // 1. Logged into your app ('connected')
    // 2. Logged into Facebook, but not your app ('not_authorized')
    // 3. Not logged into Facebook and can't tell if they are logged into
    //    your app or not.
    //
    // These three cases are handled in the callback function.
 
    FB.getLoginStatus(function(response) {
      statusChangeCallback(response);
    });
 
  };
 
  // Load the SDK asynchronously
  (function(d, s, id) {
    var js, fjs = d.getElementsByTagName(s)[0];
    if (d.getElementById(id)) return;
    js = d.createElement(s); js.id = id;
    js.src = "https://connect.facebook.net/en_US/sdk.js";
    fjs.parentNode.insertBefore(js, fjs);
  }(document'script''facebook-jssdk'));
cs


※ 로그인 상태 체크

로그인 상태 체크를 위해 사용된다. 전달되는 response에는 현재 상태와 accessToken, appId등을 담고있다.

1
2
3
FB.getLoginStatus(function(response) {
    statusChangeCallback(response);
});
cs


1
2
3
4
5
6
7
8
9
10
11
// 상태값. 자세한 설명은 개발자 페이지 참고
{
    status: 'connected',
    authResponse: {
        accessToken: '...',
        expiresIn:'...',
        reauthorize_required_in:'...'
        signedRequest:'...',
        userID:'...'
    }
}
cs


 로그인 요청

로그인 요청 호출 스크립트이다.
같이 입력되어있는 scope에 경우에는 로그인시에 접근가능한 내용에 대한 권한 요청이다. 아래 내용에서 public profile에 대한 권한과 email 정보에 대한 권한을 요청한다.

1
2
3
FB.login(function(response) {
  // handle the response
}, {scope: 'public_profile,email'});
cs

로그인 요청 스크립트가 호출되면 다음과 같이 페이스북에서 제공하는 로그인 화면이 보여진다.


※로그아웃 요청

로그인 되어있는 사용자에 대해 로그아웃을 요청한다.
1
2
3
FB.logout(function(response) {
   // Person is now logged out
});
cs

단 로그아웃을 할때는 먼저 세션의 status를 확인하고 진행해야한다. 그렇지 않고 무작정 FB.logout을 통해 로그아웃을 시도하면 다음과 같은 오류가 발생한다.
FB.logout() called without an access token.

그래서 이런식으로 계정의 상태를 확인하고 진행하자.

1
2
3
4
5
6
7
8
9
10
11
12
// 페이스북 계정 로그아웃
var faceBookLogOut = function(callback) {
    FB.getLoginStatus(function(response) {
      if (response.status === 'connected') {
          FB.logout(function(response) {
              callback();
          });
      } else {
          callback();
      }
    });
};
cs


※ 사용자 정보 요청

로그인이 된 후에 현재 로그인된 사용자의 로그인 상태를 요청하는 스크립트이다.
response의 값은 {"name": "정철", "email" : "rokking1@naver.com", "userID" : "dkfdkfjalkd"} 와 같이 전달된다.

나는 로그인 후에 이 스크립트를 사용하여 전달받은 사용자 정보를 server로 전송하여 DB에 값을 저장하고 로그인 처리하였다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var loginFacebookLoginUserInfo = function() {
    // 로그인한 사용자의 정보 얻기
    FB.api('/me', {fields: 'name,email'},  function(response) {
        let param = {};
        param.snsId = response.id;
        param.nickname = response.name;
        param.email = response.email;
 
        // 사용자 소셜 로그인 요청
        Common.sendAjax({
            url: Common.getFullPath('user/login/facebook'),
            param,
            type: 'POST',
            success: () => {
                Common.pageMove('');
            },
            failed: () => {
                alert(Common.getMessage('user.login.message.checkAccount'));
            }
        });
    });
};
cs


2. Spring Security에서 로그인 처리하기.

1번 스크립트를 통해 페이스북 로그인을 하였다. 그리고 로그인이 성공한 뒤에 받은 사용자 정보를 wedul pos 서버에 전달하여 로그인 처리하였다.

※ 사용자 정보 전달 및 저장

로그인된 사용자 정보를 전달받고 DB에 값을 저장한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// UserController.java
 
/**
   * facebook으로 로그인
   *
   * @param reqDto the req dto
   * @return the response entity
   * @throws Exception the exception
*/
@RequestMapping("/login/facebook")
public ResponseEntity<?> loginfacebook(HttpServletRequest request, UserDto reqDto) throws Exception {
    return ResponseEntity.ok(userService.facebookLogin(request, reqDto));
}
 
// UserService.java (DB에 사용자 정보 저장)
private UserDto insertSnsUser(UserDto reqDto) throws Exception {
  UserDto userDto = selectUser(reqDto);
 
  if (null == userDto) {
    if (insertUser(reqDto)) {
        return reqDto;
    } else {
        return null;
    }
  }
 
  return userDto;
}
 
cs

그리고 Spring Security에 해당 사용자의 로그인 처리를 위해서 UsernamePasswordAuthenticationToken token을 생성하고 securityContext에 Autithentication을 적용해 주었다. 

여기서 삽질을 조금 했는데 securityContext에 Autithentication을 설정만 하면 되는줄 알았는데 그게 아니라 HttpSession에 "SPRING_SECURITY_CONTEXT" 속성에 securityContext를 넣어줘야했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Override
public ResultDto facebookLogin(HttpServletRequest request, UserDto reqDto) throws Exception {
    UserDto userDto = insertSnsUser(reqDto);
 
    if (null == userDto) {
        return ResultDto.fail("등록된 사용자가 없습니다.");
    }
 
    // 인증 토큰 생성
    MyAuthenticaion token = new MyAuthenticaion(userDto.getSnsId(), "", Arrays.asList(new SimpleGrantedAuthority(Constant.ROLE_TYPE.ROLE_USER.toString())), userDto, EnumLoginType.FACE_BOOK);
    token.setDetails(new WebAuthenticationDetails(request));
    authProvider.authenticate(token);
 
    // Security Context에 인증 토큰 셋팅
    SecurityContext securityContext = SecurityContextHolder.getContext();
    securityContext.setAuthentication(token);
 
    // Create a new session and add the security context.
    HttpSession session = request.getSession(true);
    session.setAttribute("SPRING_SECURITY_CONTEXT", securityContext);
 
    return ResultDto.success();
}
cs


자세한 소스코드는 Git을 참조.

https://github.com/weduls/wedulpos_boot

댓글()

Git 저장소 Fork 후 Pull Request 및 최신 내용 갱신 방법

IT 지식/Git|2018. 10. 4. 00:34

이전직장에서도 SVN을 사용했다. 물론 GtitLab을 1년반정도 사용했으나 아쉽게도 협업하여 진행하지를 않아서 모두 master에 직접 커밋을 하였다.

그래서 이번에는 협업한다고 생각하고 시나리오를 만들어서 테스트를 진행해보자.

Github 저장소에서 상대방 Repository를 Fork하고 Pull Request를 요청해보고 변경된 최신내용을 Local에 반영하는 작업을 진행해보자.

1. 우선 Repository를 Fork 한다.


fork를 진행할 계정을 선택하고 확인을 누르면 내 Repository에 Fork된 저장소가 보이는 것을 확인할 수 있다.


2. SourceTree에 추가

Git을 Command를 사용해서 멋지게 사용하면 좋지만 실력이 부족하기 때문에 SourceTree를 사용해서 진행해보자.
SourceTree에 방금 Fork 했던 저장소를 추가해보자.


3. 소스코드 변경

Clone을 받은 코드를 내가 원했던 내용대로 수정하고 커밋과 push를 진행한다.


작업을 완료한 후 내 저장소에 가보면 정상적으로 커밋과 푸시가 완료된것을 확인 할 수 있다.


4. 변경사항 Pull Request
지금까지 진행한 내용은 내 개인 Repository에만 반영되어있다. 실제로 원래 저장소에 가보면 원래 상태 그대로인것을 확인할 수 있다.

그럼 위에 그림에서 New pull request 버튼을 누르고 비교할 브랜치를 선택 해준다.

그러면 아래와 같이 변경사항과 함께 Pull request를 만들 수 있는 화면이 나온다

그럼 코멘트를 작성하고 Pull Request를 만들어보자.

요청이 완료되었고  이제 저장소의 원래 소유자가 요청을 받아주면 작업을 완료 할 수 있습니다.


5. Pull Request 수락.

원래 Repository의 주인인 dauns 계정으로 들어가 보면 Pull Request가 하나 있는것을 확인할 수 있다.
여기서 이 요청을 거절할 수도 있고, merge 할수도 있고 rebase 할수도 있다.

테스트이기 때문에 Merge 해보자.

Merge를 하고 나면 저장소에 내용이 변경되었고 Pull Request도 사라진것을 확인할 수 있다.

6. 원격 저장소 변경사항 Local에 반영

내가 fork를 진행한 원격 저장소 내용이 변경되어서 내가 fork를 진행한 저장소와 달라졌다고 가정해보자. 

위에 그림에 보면 tt.java라는 파일이 추가되었고 내 저장소에는 저 내용이 반영되어 있지 않다.

이를 반영하기 위해서는 먼저 원래 저장소를 upstream의 이름으로 원격저장소로 추가해줍니다.


그리고 추가된 upstream에서 우측클릭을 한 후  "upstream에서 가져와 병합하기"를 선택합니다.

그러면 원격저장소의 내용이 내 Local Repository에 반영이 되었습니다. 


이 내용을 commit & push 하여 내 원격 저장소에도 반영을 해주면 완료됩니다.

확실히 GIT이 더 어렵다. 

지금이야 간단하지 꼬이면 참 귀찮아질 것 같다. 사례를 많이 만들어봐서 연습해봐야겠다.

댓글()