검색어 git rebase에 대한 글을 날짜를 기준으로 정렬하여 표시합니다. 관련순 정렬 모든 글 표시
검색어 git rebase에 대한 글을 날짜를 기준으로 정렬하여 표시합니다. 관련순 정렬 모든 글 표시

commit does not belong to any branch

# 잘못된 email 주소가 있어 수정하기 위해 아래 포스팅한 rebase 스크립트를 실행했다.
# rebase 후 tag 를 푸시하지 않았고 no branch(브랜치가 없는) 커밋으로 남게 됐다.
# git log 에는 보이지 않지만 tig cli 툴로 보면 최초 커밋 이전에 수정전 커밋이 no-branch 상태로 추가되어 보인다.

# tig 에서 봤을때 tag 커밋은 no branch 상태로 email 도 수정되지 않은 상태였다.
# 깃헙에서 no-branch 커밋을 보면 다음과 같은 메시지가 나온다.
https://github.com/xxxx/commit/{커밋해시} 
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

# 또 다음 명령으로 커밋이 포함된 브랜치를 찾아도 결과가 없다.
git branch --contain {커밋해시}

# 문제는 tig 로 보면 no-branch 커밋들이 최초 커밋 이전에 중복되어 보인다는 것이다.

# [해결방법]
# 다시 위 포스팅의 rebase 스크립트(이름,email 값 변경해서)를 실행했다.
# mater, develop 강제 푸시해도 변경사항이 없다고 나왔지만, tag 는 강제 푸시가 됐다.
git push --tags -f

# tig 에서 다시 확인해보니 email 수정된 tag 커밋이 제대로 반영됐다.(해결!)

# [로컬 refs 제거방법]
# 추가로 no branch (tag) 커밋들은 다음과 refs/.. 로만 표시된다.
refs/original/refs/tags/1.0.0
refs/original/refs/tags/1.0.1

# refs 는 로컬에 남아 있는 참조 정보라 지워도 된다.
# refs 지우기
# 방법1
# 다음과 같이 일일히 삭제하면 된다.
git update-ref -d refs/original/refs/tags/1.0.0
git update-ref -d refs/original/refs/tags/1.0.1

# 방법2
# 아래 경로의 파일들을 삭제해도 된다. 하지만 .git 내용을 직접 수정하는거 권장되지 않는다.
rm -rf .git/refs/original

# 방법3
# 삭제해야할 refs 가 많다면 이미 remote(origin) 에는 푸시됐으니 로컬에서 새로 클론 받자.
git clone http://{저장소}

# 참고로 이제 tig 에선 no branch 상태의 커밋들이 보이진 않지만
# https://github.com/xxxx/commit/{커밋해시} 에는 여전히 no branch 커밋들을 확인할 수 있다.
# rebase 가 수정된 새로운 커밋을 생성하는거고 이전의 no branch 커밋들은 유효하지 않은 상태로 github 저장소에 계속 남아 있는 것으로 보인다.
# 이 부분은 제거가 안돼서 저장소를 새로 만들어야 하는것 같다.

vim slow loading

# 언제부터인가 vim 으로 파일 열기가 아주 오래 걸린다.
# 불과 수십MB 정도 파일 오픈이 완료되기까지 수십초가 걸린다.
# 물론 설정된 .vimrc 를 지우면 빠르다.

# 테스트 파일 40MB 정도의 바이너라파일 다운로드
curl -o aws-iam-authenticator https://amazon-eks.s3.us-west-2.amazonaws.com/1.19.6/2021-01-05/bin/darwin/amd64/aws-iam-authenticator

# 파일을 열때 zzz.log 파일에 각 단계별 소요 시간 측정
vim --startuptime zzz.log aws-iam-authenticator

# 측정 결과 파일을 열어 보자.
vi zzz.log 
# 시간은 ms 단위로 각 라인은 다음 2가지 포맷 중 하나로 표시된다.
# clock   self+sourced   self:  sourced script
# clock   elapsed:              other lineskj
... 생략 ...
517.709  001.802  001.361: sourcing /Users/ysoftman/.vim/plugged/lightline.vim/autoload/lightline/colorscheme/one.vim
30908.522  000.736  000.736: sourcing /Users/ysoftman/.vim/plugged/ctrlp.vim/autoload/ctrlp/utils.vim
30920.392  30422.338: BufEnter autocommands
30920.397  000.005: editing files in windows
... 생략 ...

# BufEnter autocommand 단계가 30초가 넘는다(30422.338)
# 이 부분은 파일을 버퍼로 읽은 후 파일 타입에 맞는 셋팅들이 자동으로 실행되는 부분이다.
# 확인해보면 다수의 플러그인이 실행된다.
:autocmd BufEnter
--- Autocommands ---
filetypedetect  BufEnter
    *.xpm     if getline(1) =~ "XPM2" |   setf xpm2 | else |   setf xpm | endif
    *.xpm2    setf xpm2
NERDTree  BufEnter
    NERD_tree_*
              stopinsert
NERDTreeHijackNetrw  BufEnter
    *         call nerdtree#checkForBrowse(expand("<amatch>"))
NERDCommenter  BufEnter
    *         :call s:SetUpForNewFiletype(&filetype, 0)

... 생략 ...

vimball#ShowMesg(0,"Source this file to extract it! (:so %)")|endif
fugitive_status  BufEnter
    index     call s:ReloadWinStatus()
    index.lock
              call s:ReloadWinStatus()
fugitive_merge  BufEnter
    *         if exists('s:rebase_continue') |   exe s:MergeRebase('rebase', 0, '', [getfsize(fugitive#Find('.git/rebase-merge
/git-rebase-todo', s:rebase_continue)) > 0 ? '--continue' : '--abort'], remove(s:, 'rebase_continue')) | endif
Colorizer  BufEnter
    *         silent call colorizer#ColorHighlight(1)
youcompleteme  BufEnter
    *         call s:OnBufferEnter()
              call s:UpdateMatches()
TagbarAutoCmds  BufEnter
    *         if expand('<amatch>') !~ '__Tagbar__.*' |     let s:last_alt_bufnr = bufnr('#') | endif
              call s:AutoUpdate(fnamemodify(expand('<afile>'), ':p'), 0)


# 위에 나온 플러그인들을 .vimrc 에서 주석 처리하며 파일 오픈 해본 결과
# 다음 플러그인을 비활성화(주석처리)하면 빠르다.
# #123 처럼 #로 시작하면 컬러값을 표시해주는 플러그인으로 역시 전체 파일에서 해당 부분을 찾아 처리하는게 느린것 같다.
# 꼭 필요한 기능은 아니니 주석처리 하자.
"Plug 'lilydjwg/colorizer'

git push 된 커밋 사용자 name, email 변경

# 현재 저장소 ./git/config 에 user(name, email) 을 설정하지 않은 상태에서
# 전역 ~/.gitconfig 에 설정된 회사 user(name, email) 로
# 오랫 동안 commit , push 하고 있었다.
# github 에선 등록되지 않은 email 로 contribution 카운트가 누락된다.
# 이미 push 된 커밋들의 author(user name, email)를 변경할 수 있다.
# 참고 https://www.git-tower.com/learn/git/faq/change-author-name-email

#####

# [첫번째 방법]
# 잘못된 author 로 커밋이 일어나기 전의 커밋으로 rebase 한다.
# 잘못된 커밋 해시 이후 부터 head 까지의 커밋들을 수정할 수 있다.
# -i, --interactive 사용자가 rebase 하기전에 수정할 수 있도록 한다.
# --preserve-merge 를 옵션을 사용하지 않으면 하나의 브랜치 커밋들로 변경된다.
git rebase -i --preserve-merge 잘못된_커밋_이전_커밋_해시

# 최초 커밋부터 잘못되었다면
git rebase -i --root

# 이제 rebase 커밋 이후의 모든 커밋들이 vim 에디터로 보인다.
# 위쪽 부터가 오랜된 커밋이다.
# github 커밋 기록을 보면서 잘못된 커밋은 pick -> edit 또는 e 로 변경해 저정한다.
# 참고로 s 로 하나의 커밋을 합칠 경우 맨처음(맨위) 커밋은 pick, 그 뒤 합칠 커밋들은 s 로 변경해 저장하면 커밋 메시지들이 하나로 모인다. 여기서 메시지를 편집해서 저장한다.


# 이제 터미널에서 커밋마다 author 만 수정한다.
# 참고로 --abort 로 rebase 취소할 수 있다.
git commit --amend --author="ysoftman <ysoftman@gmail.com>" --no-edit

# rebase 계속 진행(다음 커밋으로 이동)
git rebase --continue

# 위 두과정을 커밋이 없을때까지 반복한다.
# 더이상 진행할 커밋이 없으면 다음과 같은 메시지 나온다.
Successfully rebased and updated refs/heads/master.

# master, develop, feature 등 로컬의 브랜치 마다 강제 push 한다
git push -f

# 혹시 로컬에 rebase 전 상태로 clone 받은 곳이 있고, 여기서 git pull 하면
# 이곳에선 rebase 수정전 커밋들이 그대로 남아있고 수정한 커밋들이 추가되는 형상이 된다.
# 여기서 push 하면 다시 수정한 커밋들이 푸시되니 이런 clone 은 삭제하자.

#####

# [두번째 방법]
# 우선 git pull 받아 최신 상태로 업데이트한다.
https://git-scm.com/docs/git-filter-branch
# 다음 스크립트를 이용해 한번에 변경할 수 도 있다.(완전 편함~ㅋ)
git filter-branch --env-filter '
WRONG_EMAIL="wrong@example.com"
NEW_NAME="ysoftman"
NEW_EMAIL="ysoftman@gmail.com"
if [ "$GIT_COMMITTER_EMAIL" = "$WRONG_EMAIL" ]
then
    export GIT_COMMITTER_NAME="$NEW_NAME"
    export GIT_COMMITTER_EMAIL="$NEW_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$WRONG_EMAIL" ]
then
    export GIT_AUTHOR_NAME="$NEW_NAME"
    export GIT_AUTHOR_EMAIL="$NEW_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags

# pull 표시가 나더라도 pull 없이 강제 push 한다.
# master, develop, feature, tag 등 로컬의 브랜치들을 강제 push 한다.
git push origin master -f
git push origin develop -f
git push --tags -f

# git filter-branch 를 실행해서 다음과 백업이 있어 실행하지 못한다면
# git filter-branch 뒤에 -f 로 강제(백업 덮어쓰기)할 수 있다.
Cannot create a new backup.
A previous backup already exists in refs/original/
Force overwriting the backup with -f

# 로컬에 refs/original/refs/... 참조가 보이면 삭제한다.
# 업데이트할 참조가 많다면 새로 clone 받는것이 편할 수 있다.
git update-ref -d refs/original/refs/heads/master
git update-ref -d refs/original/refs/heads/develop

#####

# 실제 커밋(contribute) 수 보다 적게 표시되는 상황


# author 수정 후 정상 카운트 되는 contributions


#####

# rebase 이전의 커밋들이 보일 수 있다.
# 이를 표시하지 않으려면 해당 release 혹윽 태그를 삭제해야 한다.
git tag -d ysoftman-release-1
git tag -d ysoftman-hotfix-1

#####

# 참고로 여러 커밋을 합치는 경우 위 vim 커밋 수정화면에서
# 방법1
# 합칠 커밋들을 s 또는 squash 로 변경해 저장한다.
# s 로 표시한 커밋과 s 바로 이전 커밋이 vim 편집 화면이 열리고 커밋 메시지를 수정하고 저장하면 s -> s 이전 커밋으로 합쳐진다.
# 방법2
# 합칠 커밋들을 f 또는 fixup 로 변경해 저장한다.
# f 로 표시한 커밋 메시지는 vim 편집 화면 없이 삭제되며 f -> f 이전 커밋으로 합쳐진다.

git command

# git 설정 확인
git config --list

# git color ui 설정
git config --global color.ui auto

# true 로 활성화하면 checkout 시에는 CRLF 로 변경되고 commit 시에는 LF 로 변경되어 커밋된다
# false 로 비활성화하면 변환없이 그대로 체크아웃, 커밋된다.
# 디폴트는 fasle 이고
# 윈도우에선 true, 맥과 리눅스에선 false 로 사용한다.
git config --global core.autocrlf  false

# git alias 를 다음과 같은 방식으로 설정 할 수 있다.
git config --global alias.br branch
git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.st status

# git diff 등에서의 컬러 사용
git config --global color.ui auto

# git 에디터를 vim 으로 설정(--system 은 전체 사용자, --global 은 현재 사용자)
git config --global core.editor vim

# git 머지툴을 vimdiff 로 설정
git config --global merge.tool vimdiff

# git 사용자 email 과 이름 설정
git config --global user.email "ysoftman@gmail.com"
git config --global user.name "ysoftman"

# 위 config 명령들은 실행후 .gitconfig 에 다음과 같이 alias 가 추가된다.
# .gitconfig 에 직접 추가해도 된다.
git config -e 또는 vi ~/.gitconfig
[color]
    ui = auto
[alias]
    br = branch
    co = checkout
    ci = commit
    st = status
[color]
    ui = auto
[credential]
    helper = cache
[core]
    editor = vim
[merge]
    tool = vimdiff
[user]
    email = ysoftman@gmail.com
    name = ysoftman

# 각 저장소마다 별도의 설정은 .git/config 를 수정한다.
vi .git/config
[user]
    email = ysoftman2@gmail.com
    name = ysoftman2

# 또는 글로벌 옵션 제거하고 설정
git config user.email "ysoftman@gmail.com"
git config user.name "ysoftman"

# git 2.0 이전에서는 push.default 를 설정해야 한다.
# matching : 원격 브랜치와 같은 이름이면 모두 푸시
# simple : 현재 브랜치만 푸시 (git2.0 부터 디폴트)
git config --global push.default simple

# pre-push, pre-commit 등의 hook 파일 경로(디폴트: .git/hooks) 변경
git config core.hooksPath .github

#####

# git 암호 저장
# ~/.git-credentials 파일 생성되며 id,pw 가 저장된다.
# 하지만 암호화 되지 않아 주의해야 한다.
git config --global credential.helper store

# 파일로 저장하지 않고 일정시간(디폴트 15분)동안 id,pw 를 캐싱한다.
git config --global credential.helper cache

# push 할때 현재 저장소 암호변경이 필요한경우
# credential.helper 변수를 제거해 id,pw 를 다시 입력 받도록 한다.
git config --unset credential.helper
git push

# osx 의 경우 credential 을 키체인(keychain access.app)으로도 관리한다.
# ~/.git-credential 내용이 osx의 키체인으로 등록된다.
# 현재 저장소의 키체인에 저정된 id,pw 를 확인한다.
git credential-osxkeychain get

# 수동으로 github.com 키체인 삭제(마지막에 엔터 2번입력해야 반영된다.)
git credential-osxkeychain erase
host=github.com
protocol=https

# 수동으로 github.com 키체인 등록(마지막에 엔터 2번입력해야 반영된다.)
git credential-osxkeychain store
host=github.com
protocol=https
username=ysoftman
password={깃헙 PAT(personal access token}

# 참고로 git push 되지만 다음과 같은 에러가 발생하는 경우가 있는데
# ~/.git-credentials newline 을 제거해야 한다.
warning: url has no scheme:
fatal: credential url cannot be parsed:

#####

# 새로운 git repository 생성(.git 디렉토리가 생성됨)하고 원격 저장소로 푸시
git init
git add -A
git commit -m "first commit"
git remote add origin git://github.com/ysoftman

# -u (--set-upstream)
git push -u origin master

# remote(origin) 저장소 변경
git remote set-url origin git://github.com/ysoftman

# 이미 존재하는 git repository 저장소를 로컬에 복사
# git 프로토콜 외 ssh, https 등 사용가능
# --recursive 옵션 사용시 링크된 repo 도 클론한다.
git clone git://github.com/ysoftman

# 클론 후 ysoftman1 브랜치로 체크아웃
git clone -b ysoftman1 git://github.com/ysoftman

# --single-branch 옵션까지 사용하면 해당 브랜치 커밋만 가져온다.
git clone -b ysoftman1 --single-branch git://github.com/ysoftman

# ssh 를 사용하는 경우
# 로컬에서 ssh 키 생성수 id_rsa.pub 를 github personal setting -> ssh and gpg key -> new ssh key 에 추가하고 다음과 같이 클론한다.
git clone git@github.com:ysoftman/ysoftman.git

# 파일 추가(스테이지에 올리기)
git add source_file.c

# 변경(수정,삭제) 있는 파일만 추가(tracked 파일중)
git add -u

# 전체 파일 추가(untracked 파일까지 포함)
git add -A

# 수정된 파일 자동 스테이지 추가하여 커밋
git commit -a

# 로컬 저장소에 반영(커밋)
git commit -m "commit comment."

# 마지막 커밋 내용 수정(push 이미 푸시 커밋은 수정하지 말자.)
git commit --amend

# 변경사항 없는 컷밋하기
git commit -m "no changes" --allow-empty

# a1234(git log 로 커밋 해시 확인) 커밋 되돌리기
# a1234 커밋 상태로 커밋한다.(자동 커밋되기 때문에 주의, reset 으로 커밋 취소 가능)
# a1234 revert 가 앞에 붙은 커밋 메시지를 사용한다.
git revert a1234

# 자동 커밋하지 않고 되돌리기
git revert --no-commit a1234

# 마지막 커밋 1개 되돌리기
git revert HEAD~1

# -X <option>, --strategy-option=<option>
# a1234(theirs)로 자동 커밋하지 않고 되돌리기
git revert -X theirs --no-commit a1234

# 머지 되돌리기
# 머지커밋을 보면 다음과 같이 브랜치의 시작(aaa)과 끝(ccc) 커밋이 명시되어 있다.
# Merge aaa ccc
# -m(--mainline) parent-number:머지된 브랜치의 시작 커밋aaa는 1이 된다.
git revert -m 1 머지커밋해시

# 현재 로컬 브랜치를 리모트에 푸시
git push

# pre-push hook 하지 않고 푸시하는 경우
git push --no-verify

# 현재 로컬 모든 브랜치를 리모트에 푸시
git push --all

# 로컬 저장소 develop 브랜치를 리모트 저장소 develop 로 푸시
# git push {remote_name} {local_branch}:{remote_branch}
git push origin develop:develop

# 현재 로컬 모든 tag들 리모트에 푸시
git push --tags

# 리모트 저장소 브랜치 내용을 로컬 브랜치에 반영(fetch + merge)
git pull

# Fetch all remotes (브랜치가 최신으로 업데이트되지는 않는다.)
git fetch --all
# 또는
git pull --all

# 리모트 저장소 master 를 로컬 master 로 pull 받기(최신으로 업데이트)
git pull origin master

# pull request 내용 받기(123 은 pr 번호다.)
git pull origin pull/123/head:pr-123

# 커밋 로그 보기
git log

# 커밋 로그 diff 도 보기(-p --patch 패치 생성)
git log -p

# 커밋 로그 diff 최신 10개 이전까지만 보기
# log 보기 화면에서 / 로 검색할 수 있다. 예) /my\ name\ is\ ysoftman
git log -p -10

# HEAD 에 tracked 파일들 보기
git ls-tree HEAD

# 스테이지에서 빼기
git reset

# 또는
# 새로 생긴 커맨드로 reset 보다 권장된다.
git restore --staged 파일명

# push 되지 않은 최근 커밋1개 취소
git reset HEAD~1

# 소스가 꼬였을때 서버 기준으로 강제로 업데이트 받기(이클립스 설정파일에서 자주 발생)
git reset --hard HEAD
git pull

# 원격 push된 잘못된 바로 이전 커밋(내역) 삭제하기
# 헤드로부터 1개 전까지 커밋 삭제(1개 이전 상태로 되돌린다.)
# 원격으로 강제 push
git reset --hard HEAD~1
git push -f

# 더이상 사용되지 않는 리모트 브랜치 제거하고 가져오기
git pull --prune
# 또는
git fetch --prune

# 리모트 브랜치 리스트 파악
git branch -r

# 로컬 브랜치 리스트 파악
git branch -a

# git branch -a 로 보면 remotes/origin/xxx 가 나오는데
# 리모트에서 삭제된 브랜치들을 로컬에 적용해 삭제할 수 있다.
git remote update --prune

# 브랜치 생성
git branch ysoftmanbranch1

# 존재하는 브랜치 체크아웃(에러 발생시 -f 옵션으로 강제 스위칭 가능)
git checkout ysoftmanbranch1

# 브랜치 생성하고 생성된 브랜치로 이동(체크아웃)
git checkout -b ysoftmanbranch2

# origin에서도 삭제된 브랜치로 체크아웃
git checkout 삭제된_브랜치_이름 커밋_해시값

# 생성된 브랜치 원격으로 처음으로 푸시하는 경우
git push --set-upstream origin ysoftmanbranch2

# 원격 브랜치가 있는경우 로컬에 체크아웃
# -t(track) 이 없으면 커밋이 안되고, 다른 브랜치로 체크아웃시 원격 브랜치가 로컬에서 사라진다.(git pull 로 최신 상태여야 한다.)
git checkout -t {업스트림이름}/{브랜치명}
git checkout -t origin/ysoftmanbranch3

# 태그로 체크아웃
git checkout tags/1.0.0

# 브랜치 삭제(삭제할 대상외의 브랜치로 스위칭되어 있어야 한다.)
git branch -d ysoftmanbranch1

# 브랜치 이름 변경
git branch -m ysoftman_old_branch ysoftman_new_branch

# 브랜치 이름 변경후 원격에도 반영할때
# 원격 브랜치 삭제
git push origin -d ysoftman_old_branch

# 이름 변경된 브랜치 원격 반영할때
git push origin ysoftman_new_branch

# 로컬 저장소 현재 디렉토리에서 지워진 파일 리스트 보기
git ls-files -d

# 로컬 현재 디렉토리에서 지워지거나 수정된 모든 파일 복구(참고로 svn 인경우 svn up)
git checkout ./

# 로컬 현재 디렉토리에서 지워지거나 수정된 특정 파일만 복구
git checkout -- ysoftman_file1.txt

# 로컬 특정 파일만 특정 시점으로 복구
git checkout 커밋해시값 -- ysoftman_file1.txt

# 리모트 저장소 정보 확인
git remote -v

# 리모트 저장소에 저장소 추가
git remote add new_remote_name remote_URL

# untracked 파일 삭제
# -f force, -d (directory)
git clean -fd

# 커밋전에 차이 보기(-U10, --unified=10 위아래 내용 10줄씩 보기)
git diff -U10

# ysoftmanbranch1 브랜치의 aaa.txt 파일과 차이 보기
git diff ysoftmanbranch1 -- aaa.txt

# 현재 상태
git status

# 현재 환경 상태
git show

# 커밋 내용 보기
git show 커밋해시

# 현재 변경내용 저장하고 HEAD 상태로 되돌리기
git stash save

# 변경 리스트 보기
git stash list

# 변경 내용 보기
git stash show

# 변경 내용 적용하기(stash 에 계속 유지)
git stash apply

# 변경 내용 꺼내기(stash 에서 삭제됨)
git stash pop

# a1234 b555 커밋 master 에 반영하기
git checkout master
git cherry-pick a1234 b555

# 로컬 태그 리스트
git tag

# 로컬 태그 원격 태그로 푸시
git push origin 1.1.1

# 원격 태그 리스트
git ls-remote --tags

# 로컬 태그 삭제
git tag --delete 1.1.1

# 로컬 0.0.1로 시작하는 태그 모두 삭제
git tag | grep "^0.1.1.*" | xargs git tag --delete

# 원격 태그(들) 삭제
git push --delete origin 1.1.1 1.1.2 1.1.3
# 또는 빈 태그를 푸시해도 삭제 된다.
git push origin :refs/tags/1.1.1

# 원격 태그 0.0.1로 시작하는 태그 모두 삭제
git ls-remote --tags | awk '{print $2}' | sed 's/refs\/tags\///' | grep "^0.0.1.*" | xargs git push --delete origin

# 0.0.1로 시작하는 태그들 로컬 태그삭제 후 원격태그도 삭제
delete_tags=$(git tag | grep "^0.1.1.*")
echo $delete_tags | xargs git tag --delete
echo $delete_tags | xargs git push --delete origin

# 대소문자 파일이름 변경
git mv --force ysoftman.TXT ysoftman.txt

#####

# 머지시 충돌 해결하기
# develop 을 최신으로 pull 해놓고 ysoftman123 에서 시작
git checkout develop
git pull
git checkout ysoftman123

# 방법1 - merge (커밋 히스토리 유지)
# develop -> ysoftman1 로 머지
git merge develop

# 충돌 부분 수정 수정
vim aaa.txt
# 또는
# develop <- ysoftman123 머지 상황에서 전략 옵션 사용하기
# -X <option>, --strategy-option=<option>
# 충돌부분 ysoftman123(theirs)로 덮어쓰기
git checkout develop
git merge -X theirs ysoftman123
# 또는
# 충돌부분 develop(ours)로 유지
git merge -X ours ysoftman123

# 커밋하고 푸시(커밋 메시지는 기본적으로 충돌 해결 내용으로 채워진다.)
git commit -a
git push

# 머지 취소할 경우
git merge --abort

# git pull 후 충돌발생시 머지 취소 후
# 현재 내가 변경한 사항으로 pull(머지)하기
git pull -s recursive -X ours

# 방법2 - rebase (ysoftman123 의 커밋들이 develop 이후 커밋들로 강제 변경된다.)
# ysoftman123 브랜치에서 develop 으로 rebase
git rebae develop

# 충돌 나는 부분을 확인
git status # 충돌되는 부분은 both modified 로 표시
git diff

# 충돌 부분 수정
vim aaa.txt

# 커밋(커밋 메시지는 기본적으로 충돌 해결 내용으로 채워진다.)
git commit -a

# rebase 계속해서 rebase 종료
git rebase --continue

# 강제 푸시, --force-with-lease 는 내 로컬에서 수정된게 아니면 덮어쓰지않아 --force 보다 안전하다.
git push --force-with-lease

#####

# 저장소 이전(migration)
# old 저장소 bare 로 클론 받기
git clone --bare https://github.com/ysoftman/old-repository.git

# new 저장소로 mirror 푸시
cd old-repository.git
git push --mirror https://github.com/ysoftman/new-repository.git

# old 저장소 삭제
cd ..
rm -rf old-repository.git

#####

# github wiki 이전
# old 저장소 wiki 클론 받기
git clone https://github.com/ysoftman/old-repository.wiki.git

# remote origin 을 new 저장소로 바꾸기
git remote set-url origin https://github.com/ysoftman/new-repository.wiki.git

# new 저장소 github -> wiki 생성하기
# Initial Home page 커밋이 발생하지만 강제 푸시하면 old 커밋히스토리만 남게된다.
# 참고로 -f 옵션없으면 "관계 없는 커밋 내역의 병합을 거부합니다" 에러가 발생한다.
git push -f

#####

# 패스워드 같은 민감한 데이터가 커밋,푸시돼 커밋히스토리 제거가 필요할때
# 모든 브랜치 및 태그에서 password.txt 파일 삭제 전 참고 및 주의사항
# 커밋에 password.txt 파일만 수정이 있었다면
# 커밋 히스토리 자체가 제거된다.
# 커밋에 password.txt 외 다른 파일 수정이 있었다면
# 커밋 히스토리는 있고 커멋내용에서 password.txt 파일만 제거된다.
# 로컬에 password.txt 도 삭제되니 rename 으로 백업해두자.
cp -v password.txt password.txt.bak
git filter-branch --force --prune-empty --index-filter 'git rm --cached --ignore-unmatch password.txt' --tag-name-filter cat -- --all

# 이제 강제 push 하면 원격 저장소에도 password.txt 관련 커밋 히스토리 또는 내용이 삭제된다.
git push -f

# filter-branch 삭제 후 원격 저장소에는 삭제됐지만
# 로컬 커밋 히스토리(git log --all)로 refs 모두를 보면 다음과 같이 백업이 있다.
# 참고로 git 은 ./git/refs 에 커밋해시(sha1,40자리의 hexadecimal)값 파일을 저장해 관리 한다.
refs/original/refs/remotes/origin/master 
refs/original/refs/heads/master

# 로컬 .git/refs 에 백업된 refs 삭제
git update-ref -d refs/original/refs/remotes/origin/master
git update-ref -d refs/original/refs/heads/master

#####

# rebase 로 브랜치 합치기(커밋들이 대상 브랜치(master)의 마지막 커밋 이후로 변경돼 커밋 이력이 깔끔해 진다.)
# ysoftmanbranch1 이 master 에 머지되기전
# ysoftmanbranch1 에서 master 로 rebase
# ysoftmanbranch1 브랜치가 아닌 master 로 기반으로 파생된 커밋으로 된다.
git checkout ysoftmanbranch1
git rebase master

# 만약 충돌이 발생하면, 충돌 수정후 rebase 계속
git rebase --continue

# 현재 HEAD 는 ysoftmanbranch1 커밋이다.
# master 에서 ysoftmanbranch1 을 머지하여 master 가 HEAD 가 되도록 한다.
git checkout master
git merge ysoftmanbranch1
# 만약 로컬에서 rebase 완료했는데 취소하고 싶다면 reflog 로 최근 rebase.. 바로전으로 HEAD 확인
git reflog
aaa111 HEAD@{1}: rebase: commit message
aaa222 HEAD@{2}: rebase: commit message
aaa333 HEAD@{3}: rebase: commit message
aaa444 (master) HEAD@{4}: rebase: checkout master
aaa555 (HEAD -> branch_test) HEAD@{5}: rebase: commit message
# reset 으로 rebase 전의 head 로 돌리면 된다.
git reset HEAD@{5}
# 참고로 위처럼 reflog 는 reset 외 commit 등 HEAD 변경 내용이 모두 기록된다.

#####

# fork 저장소에서 작업시
# 원본 저장소 최신 내용 fork 저장소에 반영하기
# upstream 으로 원래 저장소 추가
git remote add upstream "https://원본저장소"
git remote -v

# upstream 저장소 삭제
git remote remove upstream

# upstream 최신 내용 가져오기
git fetch upstream

# fork master 브랜치에 upstream 내용 머지
git checkout master
git merge upstream/master

# 현재 브랜치 upstream 으로 push 하기
git push -u upstream

#####

# 저장소 합치기
# 현재 저장소 서브디렉토리 aaa 생성해 https://github.com/ysoftman/simplePf 의 master브랜치 내용을 가져와 추가한다.
# 합쳐진 저장소의 커밋 히스토리까지 유지할 수 있다.
git subtree add --prefix=aaa https://github.com/ysoftman/simplePf master
git push