블로그 이미지
Every unexpected event is a path to learning for you. blueasa

카테고리

분류 전체보기 (2803)
Unity3D (859)
Programming (479)
Server (33)
Unreal (4)
Gamebryo (56)
Tip & Tech (234)
협업 (61)
3DS Max (3)
Game (12)
Utility (140)
Etc (98)
Link (32)
Portfolio (19)
Subject (90)
iOS,OSX (55)
Android (16)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (3)
Memories (20)
Interest (38)
Thinking (38)
한글 (30)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (18)
Exercise (3)
나만의 맛집 (3)
냥이 (10)
육아 (16)
Total
Today
Yesterday


[링크]

http://leafbird.github.io/devnote/2018/11/%ED%85%8C%ED%81%AC%EB%8B%88%EC%BB%AC-%EB%A6%AC%EB%8D%94%EC%8B%AD-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0/

반응형
Posted by blueasa
, |

병합과 재정렬은 대개 한 Topic(작업 단위)의 작업이 끝난 다음, 작업 내용을 Master branch에 반영해야 할 경우 수행하는 작업입니다.

새로운 Topic에 대한 작업을 할 때는 대개 Master Branch에서 새로운 Branch를 따서 작업한 뒤, 나중에 다시 Master Branch에 합치는 순으로 작업을 진행합니다.

병합과 재정렬에 대한 이해는 GIT으로 작업하기 위해 PM 뿐만 아니라 팀원도 알고 있어야 합니다. 병합과 재정렬에 관련된 작업 흐름을 어느 정도 이해하고 있어야 불필요한 추가 작업을 막을 수 있고, '이렇게 해도 되는데 왜 꼭 이렇게 하라고 하는거지?'라는 불만을 갖지 않게 될테니까요.^-^


특정 Commit을 선택해서 반영하기 - cherry-pick

다른 Branch에 있는 Commit을 선별적으로 현재 Branch에 반영하기 위한 명령어입니다. Cherry-pick이라는 이름에서 뭐에 쓰는 건지 예측이 될 것입니다.

체리 나무에 달려 있는 체리를 하나씩 골라 따듯이, 커밋들이 달려 있는 커밋 나무(?)에서 필요한 커밋들을 하나씩 선별해서 가져 오기 위한 명령어가 바로 cherry-pick입니다.

git cherry-pick {Commit ID}

이 때, 현재 Branch는 작업 내역을 반영할 Branch(대개 Master)여야 하고, 가져오려는 Commit이 여러개인 경우 먼저 작성한 Commit부터 순서대로 가져와야 합니다.

Cherry-pick은 엄연히 말하면 Commit을 가져 오는 것이 아니라, 가져올 Commit과 같은 Commit을 새로 만들어서 현재 Branch에 덧붙이는 작업입니다. 즉, 현재 Branch에 붙는 Commit은 Commit ID가 달라집니다.

왜냐하면 A를 X로 바꾸는 Commit과 B를 X로 바꾸는 Commit은 작업 내용이 서로 다른 Commit이기 때문입니다. 설명이 복잡해 졌는데, 이해가 잘 안간다면 다음 한 문장만 기억해 두면 됩니다.

'Cherry-pick은 Commit을 새로 하는 것과 같다.'


여러 개의 Commit을 반영하기 - rebase

Rebase는 Cherry-pick과 유사하지만, 여러 개의 Commit을 동시에 다룰 수 있습니다. 즉, Cherry-pick으로 하는 작업은 Rebase 명령어로도 할 수 있습니다. 다만, Rebase는 여러 개의 Commit을 하나로 합치거나, 특정 Commit을 건너 뛰는 등 보다 복잡한 작업을 수행할 수 있습니다.


여러 개의 Commit을 순서대로 가져와서 반영하기

대상 Branch의 변경 사항을 모두 가져와서 현재 Branch에 반영하려 할 때 다음과 같은 명령어를 사용합니다. 

즉, 현재 Branch와 대상 Branch의 공통 조상부터 대상 Branch의 마지막 Commit까지의 모든 Commit을 순서대로 하나씩 가져와서 현재 Branch에 덧붙입니다.

git rebase {가져올 Branch 이름}

결과적으로, 대상 Branch는 변경되지 않고 현재 Branch에만 새로운 Commit이 생성되어 덧붙여집니다.


Commit의 순서를 재정렬하고 첨삭하기

Rebase 명령에 -i(interactive) 옵션을 덧붙여 사용하면 Commit들의 순서를 바꾸고 첨삭하거나, 몇 개의 Commit을 하나로 합치는 등의 작업을 수행한 뒤 가져올 수 있습니다.

Rebase 명령과 -i 옵션의 조합은 '리베이시'라고도 불리우며, 병합 작업 뿐만 아니라 현재 Branch에서 최근에 작업한 몇 개의 Commit들을 편집하고자 할 때도 유용하게 사용할 수 있습니다.

예를 들어, 다음과 같이 입력하면 현재 Branch의 HEAD로부터 3개의 Commit들을 편집할 수 있습니다.

git rebase -i HEAD~3

이 때, Rebase 작업 이후 Commit들은 Cherry-pick과 마찬가지로 모두 ID가 바뀝니다.

쉽게 생각해서 위 명령은 HEAD로부터 3개의 Commit들을 현재 Branch에서 모두 '들어낸 뒤', 순서를 바꾸거나 합치는 등의 작업을 하고 다시 하나씩 새로 Commit하는 것입니다.

'리베이시' 명령은 개발을 진행하면서 은근히 많이 사용되므로 눈여겨 보는 것이 좋습니다. 특히 위에서 예로 든 명령의 경우 심심치 않게 자주 사용하게 될 것입니다.


두 개의 Branch를 하나로 합치기 - Merge


3-Way Merge

3-Way Merge란 하나의 Branch를 다른 Branch에 합치는 작업을 의미합니다. 엄연히 말하면 부모 Commit이 둘 이상인 새로운 Commit을 만들어서 현재 Branch에 덧붙이는 작업입니다.

git merge --no-ff {합칠 Branch 이름}

옵션으로 넣은 --no-ff 는 Fast-forward Merge가 가능하더라도, 무조건 3-Way Merge를 수행하라는 의미입니다.

3-Way Merge 작업을 수행하고 나면 합칠 Branch에서 가져온 Commit이 몇 개 였던지 간에 현재 Branch에는 딱 하나의 Commit만 새로 생성됩니다. 따라서, Merge를 취소하고 싶다면 새로 생성된 Commit만 삭제해 주면 됩니다.


Fast-forward Merge

Fast-forward Merge는 합칠 Branch가 현재 Branch와 분기된 이후, 현재 Branch에 새로 생성된 Commit이 없을 경우 현재 Branch를 가리키는 HEAD를 합칠 Branch의 마지막 Commit으로 옮김으로써 Merge를 수행하는 방법입니다.

뭔가 복잡한 설명이 되었는데요, 그림을 보면서 설명해 드리도록 하겠습니다.

ff-merge.png
( 그림 출처: http://www.deferredprocrastination.co.uk/blog/2012/git-un-merge/ )

왼쪽 그림은 Commit B의 위치에서 develop branch를 새로 만든 뒤, 이후 develop branch에서 C, D, E의 세 개 Commit을 작성한 상황을 나타내고 있습니다.

develop branch에서 세 개의 Commit을 새로 작성하는 동안, master branch에는 새로운 Commit이 하나도 추가되지 않았습니다. 이 상황이 바로 Fast-forward Merge가 가능한 상황입니다.

여기에서 Fast-forward Merge를 수행하면 3-Way Merge처럼 두 개의 조상을 갖는 새로운 Commit을 만들어서 master에 덧붙이는 것이 아닌, master branch를 가리키는 Commit Pointer를 E Commit으로 옮기는 것으로 Merge를 끝마치게 됩니다.

즉, 결과적으로 Master branch에서 C, D, E Commit을 새로 작성하고 E commit에 develop이라는 새로운 이름을 붙여 준 것과 같아집니다.

Fast-forward Merge는 수행 속도가 빠르고 불필요한 Branch를 없애 주는 역할을 하지만, 두 개의 branch의 구분이 사라지기 때문에 프로젝트 관리 면에서 모호함이 발생할 수 있습니다. (위 그림을 보면 master branch와 develop branch의 구분이 사라졌음을 알 수 있습니다.)

git merge {합칠 Branch 이름}

Merge 명령에 별도의 옵션을 주지 않으면 기본적으로 Fast-forward Merge를 수행합니다. 단, Fast-forward Merge가 불가능한 조건일 경우 3-Way Merge를 수행합니다.

경우에 따라서 작업 기록을 남겨 두기 위해 Fast-forward Merge를 수행하지 말아야 될 경우가 있습니다. 이 경우 --no-ff 옵션을 주어서 3-Way Merge를 수행하면 됩니다.


Rebase VS Merge

Rebase와 Merge 모두 새로운 작업 내용을 Master branch와 합치는 데 사용할 수 있는 유용한 명령어입니다. 다만, 이 둘을 각각 언제 사용해야 할 지 잘 모르겠다면 다음 문장을 기억하고 있으면 됩니다.

'Merge는 Commit ID가 보존되고, Rebase는 새로운 Commit이 생성되므로 Commit ID가 바뀐다.'

그래도 잘 모르겠다면 PM에게 물어보면 됩니다. PM이 작업을 진행하는 스타일에 따라서 작업 내용을 Main stream branch에 반영할 때 Merge를 사용할 지, Rebase를 사용할지 달라지기 때문입니다.

GIT에 처음 입문하면 Commit ID가 달라지던 말던 작업 내용이 잘 반영되면 그만이지, 뭐가 중요하냐고 생각할 수도 있습니다. 하지만, 프로젝트의 규모가 커지면 이야기가 달라집니다.

원격 저장소에는 가급적 같은 작업을 수행한 Commit이 두 개 이상 존재하지 않도록 유지해야 합니다. 같은 작업 내용을 갖는 Commit이 두 개 이상 존재하면 지저분해지고, 프로젝트 관리상 좋지 않기 때문입니다.

역사가 오랜(?) 오픈소스 작업을 할 때는 Commit Log에 작업을 위한 정보가 담겨 있는 경우가 많고, 따라서 오랜 옛날의 Commit Log를 뒤져야 하는 경우가 많습니다. 이럴 때 같은 작업을 수행한 Commit이 둘 이상이라면 그것들을 모두 살펴봐야 하는 불상사가 발생합니다.

일반적으로, 로컬 저장소에서 병합하고 Push하는지, 혹은 작업 Branch를 Push하고 병합하는지에 따라 무엇을 사용할지가 결정됩니다.

핵심은 같은 작업을 하는 Commit이 둘 이상 발생하지 않도록 하는 것이므로, 다음과 같이 구분해서 사용하면 됩니다.

Rebase

로컬 저장소에서 작업을 위해 개인적으로 만든 Branch를 Main stream branch에 반영하여 Push 하기 위해 사용합니다. 로컬에 개인적으로 만든 Branch는 Push 이후 정리를 하면서 대개 삭제합니다. 대개 Hotfix와 같이 단기간에 끝나는 Topic의 경우 이 방법으로 작업합니다.

Merge

로컬 저장소에서 분기하고 작업한 Branch를 리뷰 등을 위해 원격 저장소에서 Push한 뒤, Review가 끝나고 PM이 Main stream branch에 병합하는 순서로 작업을 진행할 때 사용합니다. Branch가 그대로 유지되기 때문에 나중에 추가 작업을 해야 할 경우나, 큰 규모의 Topic인 경우 이 방법으로 작업합니다.



[출처] https://www.tuwlab.com/ece/22218

반응형
Posted by blueasa
, |

I love Git. I was very much a TFS purist up until the last year or so, but after using Git for a while now, I’m hooked. Whilst TFS certainly isn’t bad, I love the flexibility and the fact I can muck about to my hearts content in a DVCS without affecting anyone (unless I choose to). That doesn’t mean I love everything though, one of my biggest headaches recently has been tags.

Tags in Git are simply textual markers against specific commits, very much like branches (although tags don’t move). Generally they’re used to mark points in your commit history (i.e. versions etc), but they can – being just text – be used to mark anything really.

So what’s the problem? Well, the issue isn’t with tags themselves, it’s more with the fact they’re very, very annoying to kill. I purposefully say kill and not delete, because deleting a tag is actually very simple, it’s making sure that tag staysdeleted/dead that’s the problem. Once a tag has been pushed to a remote, it is automatically retrieved during any subsequent pulls, at this point the tag exists in the user’s local repository until they choose to delete it. But it also means that said user can also then re-push a single tag – or even worse, all their local tags – to a remote when doing a push.

To illustrate this, consider the following example:

  1. Bob creates the tag ‘foo’ against a commit and pushes this to a remote
  2. Fred pulls from the remote to update his local copy of a branch he’s working on with Jane
  3. Jane does the same as Fred, meaning both Fred and Jane now have Bob’s tag ‘foo’ in their local repos
  4. Bob realises that ‘foo’ is a terrible name for a tag and wants to delete it, so he deletes the tag locally and pushes the delete to the remote
  5. Fred has written some more code he wants to share with Jane, so – using his handy Atlassian SourceTree app – he pushes his changes. But; Fred doesn’t 100% understand what he’s doing, so he checks the “Push all tags” checkbox when doing his push, thus re-pushing the tag which Bob just deleted!
  6. Bob does a further pull later that day, and lo and behold, his poorly named tag ‘foo’ has reappeared in his local repository!
  7. Jane pulls again and also pulls down the once deleted tag, much to Bob’s annoyance

Alright, so the answer here is probably to give Fred some guidance about how to use Git, but it does illustrate the real life problem I had recently, the only difference was that in my situation there were lots more developers involved.

So how do you solve this? Well, the Git documentation states that – by default – tags are not pushed unless you specify otherwise (using the “tags” switch). So actually, Git does a pretty good job of preventing people from automatically sharing all their tags, but tools like SourceTree, which provide a seductive “Push all tags” checkbox when pushing – are clearly too tempting for developers to pass up:

SourceTreePushDialog   

Another option – and probably a better one than just relying on your developers to not push their tags – is to implement a pre-receive server side hook to check whether tags are being pushed and reject the push it the user doesn’t have permission. Unfortunately, if you’re using a hosted Git repository like GitHub or Bitbucket, you’re out of luck as they don’t currently provide the ability for you to edit hooks and unfortunately don’t allow you to apply permissions to tags. This is a real shame as the functionality is already there to control access to branches.

Of course, the final option is just to accept that tags are not really meant to be deleted after they’re pushed, which is all well and good if you and your developers understand this from the start, not so good if not!


[출처] http://thecurlybracket.com/2014/10/11/git-zombie-tags-from-hell/

반응형
Posted by blueasa
, |

Last Christmas I bought my wife and myself a Synology NAS to store our pictures on. Given that I’d spent a lot of time over the last few years working on Git LFS, I always thought it would be pretty cool if you could use the NAS as an LFS server.

Like everything else these days, the thing can run apps. I looked around for what it would take to make an app for it and what I found seemed to be mostly a bunch of flaming hoops to jump through. I’m pretty lazy, so I dropped it.

The other day I was checking out Home Assistant and noticed it could be installed on the Synology via Docker. Wait … what? You can run Docker on it‽ Far out! It is Linux, so I guess that makes sense. Now it should be easy to set up an LFS server on it. We have a reference server that’ll do just fine for this.

To get running, first install the Docker app from Package Center. Start the app and head to the Registrytab. It’s hooked up to DockerHub by default. The search seems to love returning results for things you didn’t ask for, so it’s best to just search for rubyist. Searching for rubyist/git-lfs-server is far too specific, I guess, but that’s what you’re looking for. Click Download for download.

Once it’s downloaded, it’ll appear in the Image tab. Click Launch to launch.

This brings up the Docker app’s container wizard. It’s actually quite nice. Click the Advanced Settingsbutton. Set the following options in their respective tabs:

  • Advanced Settings: Enable auto-restart
  • Volume: Add a folder on the drive at a Mount Path of /var/git-lfs
  • Network: Select “Use the same network as Docker Host”
  • Environment: Configure any environment vars for the server

The full set of supported environment variables can be found in the lfs-test-server README, here are the ones you’ll need to set:

  • LFS_HOST: The host name of your NAS
  • LFS_ADMINUSER: The username of the admin user
  • LFS_ADMINPASS: The admin password

When setting LFS_HOST you’ll need to include the port that the LFS server is running on, which will be ":8080". For example, "foobar.localdomain:8080".

Once you’re done there, close the advanced settings and click the Next button. You’ll see a summary of the config. Click Apply.

Your LFS server is now running! Configure LFS by adding the following to the .lfsconfig file in the root of your repo:

[lfs]
	url="http://foobar.localdomain:8080/rubyist/myrepo"

If you have questions, tweet at @rubyist, I might answer.



[출처] https://killring.io/post/synology-for-lfs/

반응형
Posted by blueasa
, |

어느날 소스트리를 켰는데 실행이 안되는 것이었다.


그래서 아래와 같이 해보았다.

1. 프로그램 추가제거에서 삭제 후 재설치

2. 관리자 권한으로 실행

3. CMD창에서도 실행

4. 폴더삭제 ( C:\Program Files (x86)\Atlassian )



그래도 결론은 실행이 안된다!



그래서 결론은


혹시나 하는 마음에 아래의 경로를 삭제해보니 이후로는 실행이 된다.



C:\Users\name\AppData\Local\Atlassian\SourceTree.exe_Url_xx..xx




다만 단점이라면 소스트리의 초기 설정값들과 Local 저장소데이터가 다 날아간다는점이 있을 수 있겠다.



출처: http://soulduse.tistory.com/37 [프로그래밍좀비]

반응형

'협업 > Git' 카테고리의 다른 글

[펌] Git: Zombie tags from hell  (0) 2018.02.21
[펌] Synology As A Git LFS Server  (0) 2017.11.14
[링크] Pro Git[ebook]  (0) 2017.07.29
[Bug] SourceTree for Mac  (0) 2017.06.29
[Util] GitKraken  (0) 2017.06.29
Posted by blueasa
, |

[링크] Pro Git[ebook]

협업/Git / 2017. 7. 29. 02:32
반응형

'협업 > Git' 카테고리의 다른 글

[펌] Synology As A Git LFS Server  (0) 2017.11.14
[펌][SourceTree] 갑자기 실행이 안될때  (0) 2017.10.23
[Bug] SourceTree for Mac  (0) 2017.06.29
[Util] GitKraken  (0) 2017.06.29
Git: Rebase는 언제 어떻게 해야 할까?  (0) 2015.02.23
Posted by blueasa
, |

[Bug] SourceTree for Mac

협업/Git / 2017. 6. 29. 11:38



[출처] 게임코디 Rh님

반응형

'협업 > Git' 카테고리의 다른 글

[펌][SourceTree] 갑자기 실행이 안될때  (0) 2017.10.23
[링크] Pro Git[ebook]  (0) 2017.07.29
[Util] GitKraken  (0) 2017.06.29
Git: Rebase는 언제 어떻게 해야 할까?  (0) 2015.02.23
Git 도구 - 서브모듈  (0) 2015.02.04
Posted by blueasa
, |

[Util] GitKraken

협업/Git / 2017. 6. 29. 11:32


[Link] https://www.gitkraken.com/


반응형
Posted by blueasa
, |


[링크] https://trello.com/b/UTc6X4FS/-

반응형
Posted by blueasa
, |

개발 흐름


이 프로세스 문서의 현행화는 Github에서 진행되니 추후에는 Github을 방문해 주시면 고맙겠습니다.

개발 프로세스(Trello, Github, Slack)

1. Trello Card 만들기
1.1 기본적인 Trello 흐름

  • 먼저 Trello에서 개발해야 할 기능을 [To Do(Story)]라는 이름의 리스트에 카드로 만들고,
  • 해당 스토리(카드)를 개발자가 구현에 들어가면 [Doing(WIP)] 리스트에 카드를 옮기고,
  • 리뷰에 들어가면 [Review(Sprint1)] 리스트로 옯기고,
  • 개발 브랜치가 병합하여 테스트를 완료하면 [Done(Sprint1)] 리스트에 카드를 옮기고 해당 기능을 클로즈한다.



1.2 Trello카드 내용은 Description란에는 이슈 링크를 걸어주거나 wiki 링크를 걸어줘, 해당 스토리의 정보를 알 수 있도록 해준다. 그리고 Spec을 참조하여 Checklist를 추가해 완료조건을 기술해 개발해가면서 하나씩 처리해 나간다.


1.3 카드 처리 및 이동시 Slack Alert를 줘 실시간으로 처리가 가능하도록 설정한다.


2. Branch 만들고 Pull Request, Merge 하기
2.1 소스 리모트와 동기화

> git checkout master && git pull origin master && git fetch -p origin

2.2 브랜치명을 만들고 브랜치로 이동.

> git checkout -b dev_standard

2.3 작업 후 커밋.

> git commit -a -m "[VOY-201] README git 사용법 추가"
# 커밋 작성은 issue ID를 넣고 내용은 구체적으로 제시한다.

2.4 작업을 완료 후 master branch로 변경하여 remote에 새로운 변경 사항을 master에 반영

> git checkout master
> git pull origin master && git fetch -p origin

2.5 변경사항이 있다면 dev_standard branch에서 rebase를 수행

> git checkout dev_standard
> git rebase master

- rebase 중 충돌이 발생하면 아래 수행하고 아니면 넘어감.

> git add .
> git rebase --continue

2.6 Pull Request 요청하기 전에 Trello 카드도 [Review] 리스트로 옮기고 Checklist 하나를 더 만들어서 Review 내용(리뷰 담당자 포함)을 기술하면 Trello 알림을 통해 담당자가 리뷰어임을 알게 된다. 아니면 Trello 카드를 만들때 Review Checklist를 미리 만들어서 리뷰 대상자를 등록한다.
 

2.7 Pull Request 요청

> git push origin dev_standard

- push 후 Github의 repository로 이동해서 Compare & pull request 버튼 클릭하고 코멘트[To close VOY-201(jira issue 번호), 혹은 github issue 사용하면 #1234로] 남기고 Create pull request 버튼 클릭한다. 


- 이때 Pull Request 정보가 Slack을 통해 담당자에게 보내지게 되고 리뷰를 수행한다. 


- 리뷰 수행 후 수정사항이 있으면 수정 후 Pull Request를 다시 보내고, 수정 사항이 없으면 Github에서 Merge pull request를 클릭하고 Confirm merge 버튼을 클릭해서 merge를 완료한다. 

- Github에서 merge가 완료되면, Delete branch 버튼을 클릭하거나 아래 로컬에서 커맨드로 원격 브랜치를 삭제한다.(선택사항)

> git push origin :dev_standard

2.8 Review 후 수정사항이 있는 경우 수정한 다음 2.7을 재 수행한다.

2.9 로컬 master 동기화 

> git checkout master && git pull origin master && git fetch -p origin

- 로컬 브랜치 삭제(선택사항)

> git branch -d dev_standard

3. 배포하기
- 테스트 코드를 돌리고, jenkins나 자체 배포 도구를 활용하여 운영 서버에 소스를 배포한다.

4. 배포후 확인
- 기능 테스트를 눈으로 확인하면서 화면의 깨짐, 데이터의 정확성, 브라우저 호환성 등을 점검한다.
- Selenium 도구를 통해 브라우저단에서 테스트를 할 수 있는데, 이 Selenium이 구동한 브라우저의 결과 화면을 아이컨텍해서 봄으로써 어느 정도 테스트 자동화를 할 수 있다.

5. Trello 카드 Done 리스트로 이동
- 배포후 확인에서 이상이 없다면 Trello의 카드를 [Done(Sprint1 - 날짜기간)] 리스트에 이동시키고, 이슈를 close한다.




[출처] http://www.mimul.com/pebble/default/2015/06/08/1433751662702.html

반응형
Posted by blueasa
, |