20201020のGitに関する記事は8件です。

gitリポジトリの統合

準備

統合先リポジトリ:main-repo
統合されるリポジトリ:sub-repo

統合編

【Git】2つのGitリポジトリを履歴を保持して統合したい

先駆者の方がいたので同じ手順で行いました。

# 統合先リポジトリに移動
cd main-repo/

# 念の為ローカルリポジトリを最新にする
git pull

# 作業用のブランチを作成(ブランチ名:integration_repo)
git checkout -b "integration_repo"

# 統合するリポジトリを格納するためのディレクトリを作成
mkdir sub-dir

# 空ディレクトリをgit管理できるように.gitkeep作成
touch sub-dir/.gitkeep

# 一旦コミット
git add -A
git commit -m "create sub-dir"

# 統合されるリポジトリを統合先リポジトリのリモートリポジトリに追加する
git remote add sub-repo <統合されるリポジトリのURLかローカルリポジトリのPath>
git fetch sub-repo

# ちゃんとリモートリポジトリに追加されているか確認
git remote show
#=> origin
#=> sub-repo

# 統合する
git merge --allow-unrelated-histories -X subtree=sub-dir sub-repo/master 

# コミットメッセージの入力画面が開く。そのままでよければそのまま保存する

# リモートリポジトリに反映
git push --set-upstream origin integration_repo

コマンドの意味

// 調べます

影響

Q 統合元のコミット履歴は統合先にも反映されるか

される

Q これ以降、統合元のコミットは統合先にも反映されるか

されない

Q これ以降、統合先のコミットは統合元にも反映されるか

されない

Q 統合元のMRとかPRは統合先に引き継がれるか

引き継がれない

Q 統合元のタグは引き継がれるか

引き継がれない

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【初学者/自分用】gitのbranch〜pushまで詳しく解説!!

はじめに

プログラミング入門時や公式ドキュメント(Railsチュートリアルetc.)などを書くときに、
「git checkout -bとは?」「git add -A と git add . の違いって?」ってなりました。?(私だけ?)

まあ、始めから分かる人なんていません。まずは基礎からゆっくりわかればいいのです。

まずは、簡単な流れを書くと、、、(例:Railsチュートリアル)

consale
$ git checkout -b XXXX(タイトルのように、コーディングする内容をわかりやすく書く)
 #コーディングする
$ rails test #コーディングした後はテストする癖をつける

$ git add -A
$ git commit -m "comment"("comment"はどんなこと書いたか一言。) #誰が見ても分かるように
$ git checkout master
$ git merge XXXX(上のXXXXと同じことを書く)

$ rails test(確認。念のため。) #pushする前にテストする癖をつける
$ git push
$ git push github(herokuなど)

それぞれについて意味や違いを解説していくよ〜!

git checkout -b

そもそもこれは、「chekcout」と「branch」が複合していたんですよね〜
では、なぜこの組み合わせはくっつくことができるのかと言いますと、
まずはそれぞれの意味を理解する必要があります。

git checkout

「オブジェクト格納領域から指定されたファイルを取り出し、ワーキングディレクトリに配置するもの」

...意味わかんない?
大丈夫です。私もわかりません。??(なんとなく分かるくらい)
スッと意味が理解できなくても、使い方さえわかってしまえばOKです!

git branch

git add

git commit

git checkout master

git merge

git push

参考文献(※外部サイトへ飛びます。)

https://railstutorial.jp/
https://note.nkmk.me/git-add-u-a-period/

参考になったら、下の『ストック』や『LGTM』を登録するといつでも見れるようになるよ!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

git format-patchなどで複数のコミットを別のリポジトリーに変換して移植する

今日やったことのメモです。

要件

REAMDE.mdという名前のファイルをリポジトリーAに作っていくつかコミットしたが、事情が変わり別のリポジトリーBに同じ内容の変更を加えたい。しかし以下の懸念事項が:

  • コミットメッセージやdiffの内容は極力維持したい
  • ただし、リポジトリーBにはすでにREADME.mdというファイルがあるのでCODE_OF_CONDUCT.mdというファイルにリネームした状態でコミットしたことにしたい

使ったコマンドのバージョン

> git --version
git version 2.24.1.windows.2

> perl --version

This is perl 5, version 28, subversion 1 (v5.28.1) built for x86_64-msys-thread-multi

1. git format-patchで各コミットをpatchファイルとして書き出す

参考: git showを使用して複数のコミットにまたがってパッチを作成して適用する

今回はmasterブランチから生やした各コミットを、patchファイルとして再利用したかったのでgit format-patchコマンドを次のように使った:

git format-patch master

これで、masterから現在の最新のコミット(つまりHEAD)までの各コミットが、連番がファイル名の先頭に着いた.patchファイルとして書き出される。

2. リポジトリーAのREADME.mdをリポジトリーBにCODE_OF_CONDUCT.mdとしてコピーする

git format-patchで作ったpatchファイルは、例えリポジトリーが異なろうとgit amコマンドでコミットとして適用できるはずだが、そのためには、適用するコミットのうち、最初のコミットが変更を加えるファイルが、不整合しない状態で存在していなければならない。
つまり今回の場合、変更を加える前のリポジトリーAにおけるREADME.mdが、リポジトリーBにおいて、変換後の名前、CODE_OF_CONDUCT.mdとして、あらかじめコミットされている必要がある。

そこでリポジトリーAにおいてREADME.mdに変更を加える前の状態、masterブランチに戻って、リポジトリーBにCODE_OF_CONDUCT.mdとしてコピー・コミットした:

# リポジトリーAでの作業
cd /path/to/repository-a
git checkout master
cp README.md /path/to/repository-b/CODE_OF_CONDUCT.md

# リポジトリーBでの作業
cd /path/to/repository-b/
git add CODE_OF_CONDUCT.md
git commit -m"Add CODE_OF_CONDUCT.md"

3. git format-patchで作成したパッチファイルを一括置換する

今度は、最初にgit format-patchコマンドで書き出したREADME.mdに対する各patchファイルを、CODE_OF_CONDUCT.md向けに変換しよう。
やり方は単純で、perlコマンドでREADME.mdと書かれていた部分をCODE_OF_CONDUCT.mdに書き換えれば良い(もちろんsedでもなんでもいい):

perl -i.bk -pe 's/README.md/CODE_OF_CONDUCT.md/g' *.patch

当然、コミット内容にREADME.mdという文字列が含まれている場合はその部分まで変換されてしまうので少し気を遣う必要があるが、今回は特に気にする必要がなかったので、思いっきり一括置換した。
-i.bkというオプションでバックアップファイルを作るかはお好みで。

4. git amコマンドでリポジトリーBに適用する

あとは、変換した.patchファイルをリポジトリーBに移してgit amすればよい:

mv *.patch /path/to/repository-b/
cd /path/to/repository-b/
git am *.patch

以上!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CI/CDをkatacodaで体験(初心者向け) - Part9(Re-writing History)

CI/CD入門

このぺーじでは、katacodaと呼ばれる「ブラウザから無料で勉強用のインスタンスを起動できるWebサービス」を利用してCI/CDを実践します
内容は上記リンクに沿うので、不明点があればそちらへどうぞ

Gitのバージョン管理について - Scenario 9 - Re-writing History

ここでは、CI/CDとして欠かせないGitによるバージョン管理について学習します
このシナリオで学習することをさっと確認する場合は概要を確認
理解に間違い等がございましたら、ぜひご指摘ください

概要

Amending Commit Messages

リポジトリの履歴の可読性を向上させるため、git rebaseを用いて整理する
今回のシナリオはcommitの内容を変更
初期状態のcommit履歴は以下の通り

$ git log --oneline
ESC[33m254883aESC[mESC[33m (ESC[mESC[1;36mHEAD -> ESC[mESC[1;32mmasterESC[mESC[33m)ESC[m Final Item
ESC[33mb1a5bb4ESC[m New Item
ESC[33m0c3ff30ESC[m Initial comit of the list

git rebase --interactive --rootでインタラクティブモードでrootユーザとしてレポジトリを編集する
このコマンドを打ち込むと、以下のようなVimが立ち上がる

image.png

今回は"comit"とコメントされているコミットを編集するので以下のようにrewordを要求しesc,:wq

image.png

すると新たに以下のようなVimが立ち上がる

image.png

ここで、"reword"要求のcommitメッセージの変更が可能
今回は以下の通り、comit->commitに変更

image.png

terminalに戻ってきたら、変更が反映されている

$ git rebase --interactive --root
[detached HEAD d1cc84f] Initial commit of the list
 Date: Tue Oct 20 07:21:12 2020 +0000
 1 file changed, 5 insertions(+)
 create mode 100644 list.html
Successfully rebased and updated refs/heads/master.
$ git log --oneline
ESC[33m8081e1dESC[mESC[33m (ESC[mESC[1;36mHEAD -> ESC[mESC[1;32mmasterESC[mESC[33m)ESC[m Final Item
ESC[33mc6dc2adESC[m New Item
ESC[33md1cc84fESC[m Initial commit of the list   //"comit"->"commit"

Squash Commits

続いてのシナリオでは、複数のcommitをひとつにまとめる
リポジトリの初期状態は以下の通り

$ git log --oneline
ESC[33m1cf8e31ESC[mESC[33m (ESC[mESC[1;36mHEAD -> ESC[mESC[1;32mmasterESC[mESC[33m)ESC[m TODO
ESC[33ma340728ESC[m TODO
ESC[33m901fe75ESC[m TODO
ESC[33m6b4db09ESC[m TODO
ESC[33mfbf4a5dESC[m TODO
ESC[33m52204d0ESC[m TODO
ESC[33mf8f4e01ESC[m TODO
ESC[33m260d2cbESC[m TODO
ESC[33m3a1f752ESC[m Final Item
ESC[33mf74f00dESC[m New Item
ESC[33mfabfbbaESC[m Initial comit of the list
$ git rebase --interactive HEAD~8

今回は前のcommitに別のcommitを融合するのでsquash/sに要求を変更

image.png

その後、以下のように一つ目のcommitメッセージのみを残して保存

image.png

[detached HEAD d957dad] TODO
 Date: Tue Oct 20 07:43:38 2020 +0000
 1 file changed, 8 insertions(+)
 create mode 100644 TODO
Successfully rebased and updated refs/heads/master.
$ git log --oneline
ESC[33md957dadESC[mESC[33m (ESC[mESC[1;36mHEAD -> ESC[mESC[1;32mmasterESC[mESC[33m)ESC[m TODO
ESC[33m3a1f752ESC[m Final Item
ESC[33mf74f00dESC[m New Item
ESC[33mfabfbbaESC[m Initial comit of the list

commitメッセージが"TODO"一つに変更されていることを確認

Re-order Commits

続いてのシナリオでは、commitの順序を入れ替える
リポジトリの初期状態は以下の通り

$ git log --oneline
ESC[33m356b8fdESC[mESC[33m (ESC[mESC[1;36mHEAD -> ESC[mESC[1;32mmasterESC[mESC[33m)ESC[m Adding File 1
ESC[33maa0b258ESC[m Adding File 2
ESC[33md957dadESC[m TODO
ESC[33m3a1f752ESC[m Final Item
ESC[33mf74f00dESC[m New Item
ESC[33mfabfbbaESC[m Initial comit of the list
$ git rebase --interactive HEAD~2

今回は、"pick"要求のままでよいが、順序のみを入れ替える

Successfully rebased and updated refs/heads/master.
$ git log --oneline
ESC[33md49ad2bESC[mESC[33m (ESC[mESC[1;36mHEAD -> ESC[mESC[1;32mmasterESC[mESC[33m)ESC[m Adding File 2
ESC[33mb533037ESC[m Adding File 1
ESC[33md957dadESC[m TODO
ESC[33m3a1f752ESC[m Final Item
ESC[33mf74f00dESC[m New Item
ESC[33mfabfbbaESC[m Initial comit of the list

Split Commit

続いてのシナリオでは、commitの分割を行う
リポジトリの初期状態は以下の通り

$ git log --oneline
ESC[33me957a8bESC[mESC[33m (ESC[mESC[1;36mHEAD -> ESC[mESC[1;32mmasterESC[mESC[33m)ESC[m Adding Fil
ESC[33m6141321ESC[m Adding File 1
ESC[33mb150469ESC[m Adding File 2
ESC[33m2f349e4ESC[m TODO
ESC[33me5a591fESC[m TODO
ESC[33mf7de1a0ESC[m TODO
ESC[33m5637843ESC[m TODO
ESC[33m0c4df92ESC[m TODO
ESC[33m846e96dESC[m TODO
ESC[33mec5bac6ESC[m TODO
ESC[33m69440bcESC[m TODO
ESC[33me5197fdESC[m Final Item
ESC[33mdbef64cESC[m New Item
ESC[33md6dc0e6ESC[m Initial comit of the list
$ git rebase --interactive HEAD~1

image.png

今回はrebaseeditを要求

image.png

下記の結果の通り、一時的にrebaseが停止

Stopped at e957a8b...  Adding File 3 and File 4
You can amend the commit now, with

  git commit --amend

Once you are satisfied with your changes, run

  git rebase --continue
$ git reset HEAD^   //分割commitをリセット
$ git add file3.txt
$ git commit -m "File 3"
[detached HEAD f491f57] File 3
 1 file changed, 1 insertion(+)
 create mode 100644 file3.txt
$ git add file4.txt
$ git commit -m "File 4"
[detached HEAD 67edd65] File 4
 1 file changed, 1 insertion(+)
 create mode 100644 file4.txt
$ git rebase --continue   //一時停止していたrebaseを再度実行
Successfully rebased and updated refs/heads/master.
$ git log --oneline
ESC[33m67edd65ESC[mESC[33m (ESC[mESC[1;36mHEAD -> ESC[mESC[1;32mmasterESC[mESC[33m)ESC[m File 4
ESC[33mf491f57ESC[m File 3
ESC[33m6141321ESC[m Adding File 1
ESC[33mb150469ESC[m Adding File 2
ESC[33m2f349e4ESC[m TODO
ESC[33me5a591fESC[m TODO
ESC[33mf7de1a0ESC[m TODO
ESC[33m5637843ESC[m TODO
ESC[33m0c4df92ESC[m TODO
ESC[33m846e96dESC[m TODO
ESC[33mec5bac6ESC[m TODO
ESC[33m69440bcESC[m TODO
ESC[33me5197fdESC[m Final Item
ESC[33mdbef64cESC[m New Item
ESC[33md6dc0e6ESC[m Initial comit of the list

上記の結果の通り、rebaseを一時停止している間に対象のcommitをリセットしその内容を通常通り、commitすることでcommitの分割を実現

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

sourcetreeをプロキシ環境下で実行する方法

sourcetreeインストールできない

gitサーバーを作成し、sourcetreeでgit管理をしようと思っていて、プロキシ環境下windowsでインストールを試みたところ、インストールすら行えなかった。

そんな場合の対応

解消法

・アトラシアンお持ちでない場合は、アカウントを作成。

・最新のインストーラーをダウンロードします。
・インストーラーを実行します。手順を進めます。
・Atlassianログインポップアップが表示されたら、インストーラーを終了します。
・ディレクトリに移動します 。%APPDATA%\..\Local\Atlassian\SourceTree
・passwd.txtという名前の空のテキストファイルを作成します。
・accounts.jsonというJSONファイルを作成
・以下のテキストを.jsonファイルに貼り付けます。
・「YOUREMAILHERE」という単語を、アトラシアンアカウントに使用したメールに置き換えます。
・更新したjsonファイルを保存します。
・インストーラーを再実行します。
・魔法が起こる!

accounts.json
[
 {
   "$id": "1",
   "$type": "SourceTree.Api.Host.Identity.Model.IdentityAccount, SourceTree.Api.Host.Identity",

   "Authenticate": true,
   "HostInstance": {
     "$id": "2",
     "$type": "SourceTree.Host.Atlassianaccount.AtlassianAccountInstance, SourceTree.Host.AtlassianAccount",
     "Host": {
       "$id": "3",
       "$type": "SourceTree.Host.Atlassianaccount.AtlassianAccountHost, SourceTree.Host.AtlassianAccount",
       "Id": "atlassian account"
     },
     "BaseUrl": "https://id.atlassian.com/"
   },
   "Credentials": {
     "$id": "4",
     "$type": "SourceTree.Model.BasicAuthCredentials, SourceTree.Api.Account",
     "Username": "YOUR EMAIL HERE"
   },
   "IsDefault": false
 }
]

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CI/CDをkatacodaで体験(初心者向け) - Part8(Being Picky With Git)

CI/CD入門

このぺーじでは、katacodaと呼ばれる「ブラウザから無料で勉強用のインスタンスを起動できるWebサービス」を利用してCI/CDを実践します
内容は上記リンクに沿うので、不明点があればそちらへどうぞ

Gitのバージョン管理について - Scenario 8 - Being Picky With Git

ここでは、CI/CDとして欠かせないGitによるバージョン管理について学習します
このシナリオで学習することをさっと確認する場合は概要を確認
理解に間違い等がございましたら、ぜひご指摘ください

概要

  • git cherry-pick <hash>で、特定のcommitを別のbranchのマージ
    • hashは複数指定可能
    • hashA..hashBのように連続して指定可能(hashAはマージに含みたいバージョンの一つ手前)
  • マージの際にconflictが発生した場合はgit mergeの際とほぼ同じ方法で解決可能
    1. git cherry-pick <hash>
    2. conflict発生
    3. git checkout --ours/theirs <file>
    4. git add
    5. git cherry-pick --continue(git commitは利用しない)

Step 1 - Cherry Picking

Gitを用いた開発では、master等から分岐したbranch上でcommitを繰り返し、統合する
git mergeでは、分岐後のcommitをすべて反映させるが、git cherry-pickは指定したcommitのみを反映させることが可能
このシナリオでは、new_branchの3世代前のバージョン、2世代前のバージョン、最新版をmasterに統合

$ git log --pretty=oneline --reverse new_branch
ESC[33m35bb08aa4d80d2214e7af28207af8e9312fd3250ESC[m Readme File
ESC[33m35182d3434fe6011c2a15c635e35bd61e5ff9c89ESC[m Initial commit, no items
ESC[33mfc5e301c9ccf0465599f3be8b71403e2be794b7aESC[m Initial list
ESC[33m2dc5608b8c88d38fd80235e1072da57d8b3c94ccESC[m Creating Second List
ESC[33m6aef159d692bb73f3f7860741d1877c44da58e59ESC[mESC[33m (ESC[mESC[1;32mnew_branchESC[mESC[33m)
$ git branch -va
* ESC[32mmaster    ESC[m 63b66b2 Empty list
  new_branchESC[m 6aef159 Adding final items to the list
$ git log --oneline
ESC[33m63b66b2ESC[mESC[33m (ESC[mESC[1;36mHEAD -> ESC[mESC[1;32mmasterESC[mESC[33m)ESC[m Empty list
ESC[33m35bb08aESC[m Readme File
$ git cherry-pick new_branch~3
[master 1e1c393] Initial commit, no items
 Date: Tue Oct 20 03:22:58 2020 +0000
 1 file changed, 2 insertions(+)
 create mode 100644 list.html
$ git log --oneline
ESC[33m1e1c393ESC[mESC[33m (ESC[mESC[1;36mHEAD -> ESC[mESC[1;32mmasterESC[mESC[33m)ESC[m Initial co
ESC[33m63b66b2ESC[m Empty list
ESC[33m35bb08aESC[m Readme File
$ git cherry-pick new_branch~2
[master 4b77632] Initial list
 Date: Tue Oct 20 03:22:59 2020 +0000
 1 file changed, 3 insertions(+)
$ git log --oneline
ESC[33m4b77632ESC[mESC[33m (ESC[mESC[1;36mHEAD -> ESC[mESC[1;32mmasterESC[mESC[33m)ESC[m Initial li
ESC[33m1e1c393ESC[m Initial commit, no items
ESC[33m63b66b2ESC[m Empty list
ESC[33m35bb08aESC[m Readme File
$ git cherry-pick new_branch
[master 981a34f] Adding final items to the list
 Date: Tue Oct 20 03:22:59 2020 +0000
 1 file changed, 1 insertion(+)
$ git log --oneline
ESC[33m981a34fESC[mESC[33m (ESC[mESC[1;36mHEAD -> ESC[mESC[1;32mmasterESC[mESC[33m)ESC[m Adding fin
ESC[33m4b77632ESC[m Initial list
ESC[33m1e1c393ESC[m Initial commit, no items
ESC[33m63b66b2ESC[m Empty list
ESC[33m35bb08aESC[m Readme File

また、git cherry-pickは以下のように一度に複数のcommitを処理することも可能

$ git cherry-pick new_branch~3 new_branch~2 new_branch
[master feaed88] Initial commit, no items
 Date: Tue Oct 20 03:36:35 2020 +0000
 1 file changed, 2 insertions(+)
 create mode 100644 list.html
[master 1d8352d] Initial list
 Date: Tue Oct 20 03:36:35 2020 +0000
 1 file changed, 3 insertions(+)
[master dce035e] Adding final items to the list
 Date: Tue Oct 20 03:36:35 2020 +0000
 1 file changed, 1 insertion(+)
$ git log --oneline
ESC[33mdce035eESC[mESC[33m (ESC[mESC[1;36mHEAD -> ESC[mESC[1;32mmasterESC[mESC[33m)ESC[m Adding fin
ESC[33m1d8352dESC[m Initial list
ESC[33mfeaed88ESC[m Initial commit, no items
ESC[33m5dae15aESC[m Empty list
ESC[33m89d91d5ESC[m Readme File

他にも連続するcommitを<commitA>..<commitB>のように指定することも可能

$ git cherry-pick new_branch~4..new_branch~2
[master f6e3642] Initial commit, no items
 Date: Tue Oct 20 03:45:21 2020 +0000
 1 file changed, 2 insertions(+)
 create mode 100644 list.html
[master 4b7a909] Initial list
 Date: Tue Oct 20 03:45:21 2020 +0000
 1 file changed, 3 insertions(+)
$ git cherry-pick new_branch
[master b71ad13] Adding final items to the list
 Date: Tue Oct 20 03:45:21 2020 +0000
 1 file changed, 1 insertion(+)
$ git log --oneline
ESC[33mb71ad13ESC[mESC[33m (ESC[mESC[1;36mHEAD -> ESC[mESC[1;32mmasterESC[mESC[33m)ESC[m Adding fin
ESC[33m4b7a909ESC[m Initial list
ESC[33mf6e3642ESC[m Initial commit, no items
ESC[33me44b269ESC[m Empty list
ESC[33me477a69ESC[m Readme File
(END)

Step 2 - Resolving Cherry Picking Conflict

step2,3では、git cherry-pickによるマージでコンフリクトが発生した場合の対処を説明

$ git cherry-pick new_branch~1
error: could not apply 65f1b54... Creating Second List
hint: after resolving the conflicts, mark the corrected paths  //conflictの発生
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'
$ git status
On branch master
You are currently cherry-picking commit 65f1b54.
  (fix conflicts and run "git cherry-pick --continue")
  (use "git cherry-pick --abort" to cancel the cherry-pick operation)

Unmerged paths:
  (use "git add <file>..." to mark resolution)

        both added:      list2.html   //git mergeの際と同様、conflict状態

no changes added to commit (use "git add" and/or "git commit -a")
$ git diff
ESC[1mdiff --cc list2.htmlESC[m
ESC[1mindex 4d4407a,ae60808..0000000ESC[m
ESC[1m--- a/list2.htmlESC[m
ESC[1m+++ b/list2.htmlESC[m
ESC[36m@@@ -1,3 -1,6 +1,10 @@@ESC[m
  <ul>ESC[m
ESC[32m++<<<<<<< HEADESC[m   //master上のlist2.html
ESC[32m +<li>Empty</li>ESC[m
ESC[32m++=======ESC[m   //new_branch上のlist2.html
ESC[32m+ <li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>ESC[m
ESC[32m+ <li>Aliquam tincidunt mauris eu risus.</li>ESC[m
ESC[32m+ <li>Vestibulum auctor dapibus neque.</li>ESC[m
ESC[32m+ <li>dapibus neque.</li>ESC[m
ESC[32m++>>>>>>> 65f1b54... Creating Second ListESC[m
  </ul>ESC[m
$ git checkout --theirs list2.html   //new_branch上のlist2.htmlの結果を優先

Step 3 - Continuing Cherry Picking After Conflict

step2にて、conflictの発生を確認、優先する変更を指定
ここでは、優先結果の反映されたcommitを実行
基本的には、git mergeの際と同じ手順だが、git commitの代わりにgit cherry-pick --continueを用いる

$ git log --oneline
ESC[33mb71ad13ESC[mESC[33m (ESC[mESC[1;36mHEAD -> ESC[mESC[1;32mmasterESC[mESC[33m)ESC[m Adding final item
ESC[33m4b7a909ESC[m Initial list
ESC[33mf6e3642ESC[m Initial commit, no items
ESC[33me44b269ESC[m Empty list
ESC[33me477a69ESC[m Readme File
$ ls -a
.  ..  .git  list2.html  list.html  README.md
$ cat list2.html
<ul>
<li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
<li>Aliquam tincidunt mauris eu risus.</li>
<li>Vestibulum auctor dapibus neque.</li>
<li>dapibus neque.</li>
</ul>
$ git status
On branch master
You are currently cherry-picking commit 65f1b54.
  (fix conflicts and run "git cherry-pick --continue")
  (use "git cherry-pick --abort" to cancel the cherry-pick operation)

Unmerged paths:
  (use "git add <file>..." to mark resolution)

        both added:      list2.html

no changes added to commit (use "git add" and/or "git commit -a")
$ git add list2.html
$ git status
On branch master
You are currently cherry-picking commit 65f1b54.
  (all conflicts fixed: run "git cherry-pick --continue")
  (use "git cherry-pick --abort" to cancel the cherry-pick operation)

Changes to be committed:

        modified:   list2.html

$ git cherry-pick --continue   
[master aa8d155] Creating Second List cherry-pick
 Date: Tue Oct 20 03:45:21 2020 +0000
 1 file changed, 4 insertions(+), 1 deletion(-)
$ git log --oneline
ESC[33maa8d155ESC[mESC[33m (ESC[mESC[1;36mHEAD -> ESC[mESC[1;32mmasterESC[mESC[33m)ESC[m Creating Second L  
ESC[33mb71ad13ESC[m Adding final items to the list
ESC[33m4b7a909ESC[m Initial list
ESC[33mf6e3642ESC[m Initial commit, no items
ESC[33me44b269ESC[m Empty list
ESC[33me477a69ESC[m Readme File

ログの結果Creating Second Lからconflictが発生したcommitをmasterに反映できたことを確認

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

マージ先?マージ元?リベース先?リベース元?

CUIとGUIを併用すると、よく操作を間違えるのでメモ。

Mergeとは

〈…を〉〔…に〕溶け込ませる,没入させる; 併合する 〔into〕.
The companies were all merged into one giant conglomerate. 会社は全部併合されて巨大な複合企業になった.
―― Weblio辞書

「AをBにマージしますか?」
⇒ Aが消えてBが残る。Aがマージする側(マージ元)、Bがマージされる側(マージ先)。

「現在のブランチに'xxx'をマージしても本当によろしいですか?」
⇒ 'xxx'が消えて現在のブランチが残る。'xxx'がマージ元、現在のブランチがマージ先

Mergeを使って、Featureを取り入れたDevelopをつくる

  • Developをメインブランチにして、Featureをマージする
    • 現在のブランチがマージ先になる
% git checkout develop
% git merge feature

Rebaseとは

  1. 新しいベース[土台・基準レベル]を~に設定する ―― 英辞郎

「現在のブランチを'yyy'にリベースしてもよろしいですか?」
⇒ 現在のブランチについて、新しいベースを'yyy'に設定して再構築する

Rebaseを使って、Developの更新分を組んだFeatureをつくる

  • Featureをメインブランチにして、Developでリベースする
    • 現在のブランチがリベース先になる
% git checkout feature
% git rebase develop

結論

現在のブランチを主役として取り込むイメージ。
GUIツールの文言はしっかり読もう。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Git で特定のブランチを別リポジトリとして分割する

TL;DR

  • Gitで複数のプロジェクトが1つのリポジトリに混在しブランチ=プロジェクトという扱いとなってしまった場合に、履歴を残した状態でブランチを別のリポジトリに分割する方法を記載します。

前提

  • リモートリポジトリへの変更の反映は行われていること。

環境

構成

名称
分割元リポジトリ repoA
分割元ブランチ repoA-branchB
分割元サブフォルダ repoA-branchB-folderC
分割先リポジトリ repoB

変更前

repoA  <--> http://hogehoge/repoA.git
├─master
└─remotes/origin
    ├─branchB
    │  └─folderC
    │      ├─subfolderD
    │      ├─subfolderE
    │      └─subfolderF
    └─master

変更後

branchAfolderBをrepoBとして分割する。

分割元

repoA  <--> http://hogehoge/repoA.git
├─master
└─remotes/origin
    └─master

分割先

repoB  <--> http://hogehoge/repoB.git
└─master
    ├─subfolderD
    ├─subfolderE
    └─subfolderF

手順

  1. コマンドプロンプト、またはGit Bashを開きます。

  2. 作業フォルダを新しいリポジトリを作成したい場所に移動します。

  3. 分割したいフォルダのあるリポジトリをクローンします。

    git clone https://hogehoge/repoA
    
  4. 作業フォルダをクローンしたリポジトリに移動します。

    cd repoA
    
  5. ブランチを切り替えます。

    git checkout branchB
    
  6. 現在のブランチが切り替わっていることを確認します。

    git branch
    > * branchB
    >   master
    

    ? 特定のブランチを分割するためブランチを移動しています。

  7. 作業フォルダをリポジトリの親フォルダに移動します。

    cd ..\
    
  8. ローカルでリポジトリをクローンします。

    git clone repoA repoB
    
  9. 作業フォルダをクローンしたリポジトリに移動します。

    cd repoB
    
  10. ローカルブランチが切り替えたブランチのみになっていることを確認します。

    git branch
    > * branchB
    

    ? ブランチを切り替えてからローカルでリポジトリをクローンすることで、切り替えたブランチのみとなります。

  11. 分割したいフォルダが一つのフォルダにまとまっていない場合は、git mvコマンドで移動してフォルダにまとめます。

    覚えておくと便利なGitコマンド - Qiita

    ? エクスプローラーで移動してもリポジトリには移動としては記録されません(削除と追加となります)ので、git mvコマンドを使用する必要があります。

  12. リポジトリのファイルからサブフォルダを抽出するには、以下の情報を指定して git filter-branch を実行します。

    例文
    git filter-branch --prune-empty --subdirectory-filter FOLDER-NAME HEAD
    

    ? FOLDER-NAME: 別のリポジトリの作成元にしたいプロジェクト内のフォルダです。
    ? --prune-emptyがあると、コメントのみの空commitを消去してくれます。

    実施
    git filter-branch --prune-empty --subdirectory-filter folderC HEAD
    
  13. repoAのルートに配置された必要な.gitignoreがあった場合にはリポジトリに追加します。

    git add .gitignore
    git commit -a -m "任意のコメント"
    
  14. リモートリポジトリ上で新しいリポジトリを作成し、リモートリポジトリ URLをコピーします。

    ? Azure DevOps (Server) の手順
     チームプロジェクト内に複数のリポジトリを作成することが可能です。
    ? GitHubの手順

  15. リポジトリの既存のリモート名を確認します。

    git remote -v
    > https://hogehoge/repoA (fetch)
    > https://hogehoge/repoA (push)
    
  16. 既存のリモート名および新しいリモートリポジトリ URL を使って、新しいリポジトリの新しいリモート URL をセットアップします。

    git remote set-url origin https://hogehoge/repoB
    
  17. リモートURLが変更されたことを確認します。

    git remote -v
    > https://hogehoge/repoB (fetch)
    > https://hogehoge/repoB (push)
    
  18. ブランチ名を変更します。

    git branch -m branchB master
    
  19. ブランチを確認します。

    git branch
    > * master
    
  20. リポジトリをリモートリポジトリにプッシュします。

    git push -u origin --all
    
  21. ローカルのremotes/origin内の不要なブランチを消すため、フォルダを消して再取得します。

    git branch -a
    > * master
    >   remotes/origin/HEAD -> origin/branchB
    >   remotes/origin/branchB
    >   remotes/origin/master
    
    cd ..\
    

    エクスプローラーからrepoBフォルダを削除します。
    ? 誤操作を避けるため、CUIコマンドは記載していません。

    git clone git clone https://hogehoge/repoB
    
    cd repoB
    
    git branch -a
    > * master
    >   remotes/origin/HEAD -> origin/master
    >   remotes/origin/master
    
  22. リモートリポジトリから分割済みのブランチ「branchB」を削除します。

    ブランチ削除時は慎重に作業してください!

    ? Azure DevOps (Server) の手順
     image.png
    ? GitHubの手順
    ? コマンドでの手順

参考資料

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む