ラベル Git の投稿を表示しています。 すべての投稿を表示
ラベル Git の投稿を表示しています。 すべての投稿を表示

2014年10月23日木曜日

[Git]過去のリビジョンに戻る場合でのgit checkoutとgit reset --hardの違い

このエントリーをはてなブックマークに追加 はてなブックマーク - [Git]過去のリビジョンに戻る場合でのgit checkoutとgit reset --hardの違い

仕事で過去のリビジョンに戻る方法はどうすれば良いのか?という質問があったのだが、git checkoutとgit reset –hardを使う場合の違いについてよく分かってなかったので調べてみた。

指定リビジョンに戻す

既に記載の通り、2つやり方がある。

$git checkout <commit>

もしくは

$git reset --hard <commit>

である。

ただし、二つは大きな違いがある。

git checkout <commit>

指定されたコミットIDのリビジョンに作業ディレクトリ内のファイルが変更される。ブランチは detached HEAD状態となり、この状態ではコミットなどを行ってもリポジトリに保存されない。(厳密には少し違うが) つまり、read only状態で指定リビジョンの状態確認が出来る。

元のブランチに戻る場合、以下のように元々のブランチ名を指定すれば良い。

$git checkout master

基本的にread onlyであるが、別途ブランチを作成する事で、リポジトリへの追記も可能。

git reset --hard <commit>

現在のブランチのまま、指定されたリビジョンに作業ディレクトリ、ステージング環境、HEADが変わる。もし作業ディレクトリに編集中のファイルがあったという場合にもその情報は失われてしまうので、実行の際には注意が必要。

また、元々のHEADの状態に戻る場合、git reflogを使うかORGI_HEADを使う必要がある。

$git reset --hard ORIG_HEAD

もしくは

$git reflog
$git reset --hard <commit>

結論

大半の場合、checkoutによる操作で事足りそう。そして、checkoutの方が安全。

参考

The git checkout Command

The git reset Command

detached HEAD状態から元に戻すコマンド (git, checkout, fix a detached HEAD, .git/HEAD, refs/heads/master)

git reset についてもまとめてみる

2014年10月14日火曜日

[Git]ローカルのコミットは入れず、リモートリポジトリの更新内容をブランチに取り込む

このエントリーをはてなブックマークに追加 はてなブックマーク - [Git]ローカルのコミットは入れず、リモートリポジトリの更新内容をブランチに取り込む

状態

  • masterブランチ。ローカルで1回コミットを行った。その後、リモートリポジトリが他のメンバーによって更新された。
  • devブランチ。ローカルで1回コミットをする前の状態のmasterからブランチを作成している。

やりたいこと

masterブランチのリモートリポジトリで行われた変更のみをdevブランチに反映したい。 ただし、masterブランチでのローカルで行われたコミット内容はdevブランチに反映したくない。

結論

$git fetch
$git checkout dev
$git merge origin/master

fetchでorigin/masterリモートブランチを最新化し、devブランチにorigin/masterをmergeする。

本作業と同時にmasterブランチにリモートリブランチ(origin/master)のコミットを反映しても良い場合には以下でもOK。

$git pull
$git checkout dev
$git merge origin/master

git pullはgit fetchとgit mergeを実行するので、上記だとmasterブランチも変更される。 単純にやりたいことだけやるのであれば、git fetchの方が合っていると思われる。

追記(11/23) トピックブランチにマスターの変更を反映することを2回以上行うと大量のコンフリクトが発生する。

gitで双方向にmergeしているとひどいはまり方をすることがある件

上記より、トピックブランチへマスターの変更を反映するのはマスターへマージする直前のみとし、それ以外の場合にはマスターからブランチを再作成し、cherry-pickなどを利用するのが良いと思われる。

これは駄目

$git pull
$git checkout dev
$git merge master

これを実行するとローカルのコミットもdevブランチに反映されてしまうのでNG。

大切な事

  • git pullとはgit fetchとgit mergeが行われている事を意識する
  • git fetchが実行されると作業ディレクトリの内容はは変更されず、リモートブランチ(orgin/masterなど)のみが変更される
  • masterブランチとリモートブランチ(origin/master)ブランチは別のブランチでである

参考にさせて頂きました

2014年5月23日金曜日

外部のbareリポジトリとオレオレGitlabを連携させてみる

このエントリーをはてなブックマークに追加 はてなブックマーク - 外部のbareリポジトリとオレオレGitlabを連携させてみる

オレオレGitlabを構築して、外部のbareリポジトリと連携してみたのでその時のメモ。 (メール機能については除外)

状況

  • 外部サーバーにGitのbareリポジトリがある
  • 外部サーバーにGitlab立てたいけど色々あって却下された
  • じゃあ社内ネットワークにGitlab立ててHookさせれば良いんじゃね?
  • VagrantでVM立ててそこにGitlab立てよう

完成イメージ

環境

  • ホストマシン:Mac OSX 10.9.3
  • VM:Ubuntu12.04(64bit)
  • Vagrant1.6.2
  • Gitlab 6.8.2

UbuntuのVMを起動する

Gitlabが簡単にインストール出来るOmnibusが利用出来るUbuntu12.04(64bit)のVMを立てます。

まずはVagrantfileを用意。大切な箇所だけ抜粋。

# ubuntu12.04 64bitのBOXを予めインストール
config.vm.box = "precise64"

# 80ポートへのフォワード設定
config.vm.network "forwarded_port", guest: 80, host: 1234

起動させます。

$vagrant up

GitLabのインストール

まずはsshアクセスします。

$vagrant ssh

GitlabをVMにインストールします。 取得するGitLabのOmnibusの最新版は こちらで確認し、各自変更してください。

$wget https://downloads-packages.s3.amazonaws.com/ubuntu-12.04/gitlab_6.8.2-omnibus-1_amd64.deb
$sudo dpkg -i gitlab_6.8.2-omnibus-1_amd64.deb
$sudo gitlab-ctl reconfigure

インストールが終わったか、確認します。

$wget http://localhost:8080/

外部からのアクセスする際のURLを設定します。

$sudo vi /etc/gitlab/gitlab.rb
external_url "http://localhost"
$sudo chmod 600 /etc/gitlab/gitlab.rb

再度設定をします。

$sudo gitlab-ctl reconfigure

本例の場合、ブラウザからhttp://localhost:1234/でアクセスします。 実際に会社などで利用する場合には自身のマシンに設定されているIPアドレスでも接続出来るはずです。なお、その場合、gitlab.rbのexternal_urlもマシンに降られているIPアドレスを記述する必要があります。

最初のログインはID「root」、パスワード「5iveL!fe」と入力します。

bareリポジトリをGitLabにも追加する

本例では確認他の為にGithubを利用します。 まず、Githubに適当なプロジェクトを作成します。

その後、該当のプロジェクトのgit cloneする時のURLをメモします。

GitlabのNew ProjectでImport existing repository?を選択し、先ほどコピーしたURLにユーザー名とパスワードを設定して指定します。(https://username:password@gitlab.com/company/project.git. など)

上記によってGitLabにbareリポジトリを作成されます。

bareリポジトリは/var/opt/gitlab/git-data/repositories/{namespace}/配下に配置されています。

git configコマンドで確認すると以下のようになっており、originはGithubとなっている事が確認出来ます。

$cd /var/opt/gitlab/git-data/repositories/root/helloworld.git
$git config -l
core.repositoryformatversion=0
core.filemode=true
core.bare=true
remote.origin.url=https://username:password@github.com/toshihirock/Hello-World.git

Gitabへのpush時に取得元のリポジトリにもpushするようにする

Gitlabへのpushタイミングで取得元にもpushする為にHookスクリプトを利用します。

こちらは以下のサイトを参考にさせてもらいました。

git hooks を利用したデプロイを導入しました

gitでbareリポジトリを同期する方法

まず、直接取得元へpushするユーザーが居る事もあると思うので、push時に取得元とGitLabとの間で同期を取るようにします。 この方法を実現する為に、pushの取り込み前に実行されるpre-receiveスクリプトを利用します。

$su git
$cd hooks
$touch pre-receive
$chmod +x pre-receive
$vi pre-receive

編集します。

#!/bin/bash
echo "start pre-receive"
git fetch origin 'refs/heads/*:refs/heads/*'
echo "end pre-receive"

これで取得元の差分があれば取り込む事が出来ます。

また、post-updateスクリプトを利用してGitlabへのpushが完了したタイミングで、取得元にもpushするようにします。 post-receiveスクリプトといのもあるのですが、こちらは複数のブランチへのpushの際にも一度しか呼ばれないので、今回の用途ではブランチ毎に呼び出されるpost-updateスクリプトを利用します。

$touch post-update
$chmod +x post-update
$vi post-update

編集します。

#!/bin/bash
echo "start post-update"
BRANCH=$(git rev-parse --symbolic --abbrev-ref $1)
git push origin ${BRANCH}
echo "end post-update"

上記のようにすると変数BRANCHにpushしたブランチ名が入るので、対象のブランチを取得元にpushすることができます。 先ほどgit configで見たようにGitlabに作成されたbareリポジトリのoriginは取得元(本例だとGithub)となっているので上記のようにすることで取得元へのpushが出来ます。

Gitlabからのクローンを確認

Gitlabからクローン出来るか確認してみます。 ユーザー名、パスワードは置き換えて下さい。

$git clone http://username:password@localhost:1234/root/helloworld.git

Githubからのクローンとpush先の変更

Githubから対象のリポジトリをcloneします。

$git clone http://username:password@github.com/hogefuga.git

git remoteコマンドを利用してoriginの向き先をGitlabに変更します。

$git clone Github url
$git remote set-url origin http://username:password@localhost:1234/root/helloworld.git

originの向き先がGitlabとなっている事を確認します。

$git config remote.origin.url 

pushしてみる

ではcloneしてきたリポジトリを編集してGitlabにpushし、その後、Githubに反映されているか確認します。

$vi README
$git add .
$git commit -m "Github"
$git push origin master
Hello-World [master] git push origin master
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 262 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: start pre-receive
remote: end pre-receive
remote: start post-update
remote: To https://username:password8@github.com/toshihirock/Hello-World.git
remote:    e9c6f5f..35d1433  master -> master
remote: end post-update
To http://username:password@localhost:1234/root/helloworld.git
   e9c6f5f..35d1433  master -> master

上記のようにHookスクリプトで標準出力される内容ははpush時に確認出来ます。(ユーザー名、パスワードは変更しています)

上記実施後、Githubでもpushしたコメントが反映されている事を確認できました。

また、上記の場合には取得元のパスワードがバレバレになるのでその場合にはpost-updateを以下に変更すれば出力がされないようになります。

git push origin ${BRANCH} >/dev/null 2>&1

本例ではhttpプロトコルで確認しましたが、sshプロトコルでも可能です。

2014年3月21日金曜日

JenkinsのGitPluginでコメントが文字化けした時の解消方法

このエントリーをはてなブックマークに追加 はてなブックマーク - JenkinsのGitPluginでコメントが文字化けした時の解消方法

UbuntuにJenkinsをインストールしてGitPluginを入れて連携させた時にコミットコメントが文字化けしたので解消方法をメモ。

原因はJenkinsのファイルエンコーディングがUTF–8になっていないためなので、これを直す。

パッケージインストール(apt-getなど)の場合、/etc/default/jenkinsにJAVA_ARGS=“-Dfile.encoding=utf–8”を追記してJenkinsをリスタートすればOK

$sudo vi /etc/default/jenkins
JAVA_ARGS="-Dfile.encoding=utf-8"
$sudo service jenkins restart

これで直るはず。

warを利用してtomcatで動かしている場合、CATALINA_OPTSにDfile.encoding=utf–8を指定した後に起動すればOK。

Tomcatユーザーで起動している場合、

$vi ~/.bashrc
CATALINA_OPTS="-Dfile.encoding=utf-8"
export CATALINA_OPTS
$source ~/.bashrc

としてtomcatを再起動すれば問題ないはず。

参考

Ubuntu 12.04にJenkinsをインストールしてApacheでポート80で動かす

CATALINA_OPTSの指定

2014年1月27日月曜日

VagrantのProvisioning機能を利用してVM起動時にGitリポジトリ作るようにしてみた

このエントリーをはてなブックマークに追加 はてなブックマーク - VagrantのProvisioning機能を利用してVM起動時にGitリポジトリ作るようにしてみた

Gitのリモートリポジトリを作る必要がありそうな感じだったので、試しにVagrantのProvisioning機能を利用してVM起動時にGitのリモートリポジトリを作るshellを作って試してみたのでその時のメモ。

前提条件

  • ホストマシーンはMacOSX10.9.1で、Gitはインストール済み
  • 仮想環境はCentOS6.4を利用
  • 仮想環境にGitのリモートリポジトリを作成し、ホストマシーンでcloneしたり出来るまでを実施

目次

  1. Vagrantのインストール
  2. Vagrantを利用したCentOS仮想環境の構築
  3. 仮想環境のCentOSの作成、起動
  4. 仮想環境にプライベートIPアドレスを設定する
  5. 仮想環境にGitのリモートリポジトリ作成
  6. まとめ
  7. 参考サイト

1.Vagrantのインストール

Vagrantを利用する際にはVirtualBoxが必要なので予めインストールしておきます。

Vagrantの公式サイトのDownloadからOSにあったVagrantをダウンロードしてインストールします。(たしかOK連打でOKだったはず)

2014年1月26日現在以下のOSのものが配布されているようです。

  • MacOSX(32bit or 64bit)
  • Windows(32bit or 64bit)
  • Debian/Ubuntu(32bit or 64bit)
  • CentOS/Fedora/Redhat(32bit or 64bit)

インストールが完了するとTerminalでvagrantコマンドが使えるようになっているはずです。

$vagrant --version
Vagrant 1.4.3

2. Vagrantを利用したCentOS仮想環境の構築

注意:Boxの取得は大きなファイルのダウンロードとなる為、通信速度が早い所で実施するのがおすすめです

Vagrantで任意のOSの環境を構築する際に対応するOSのBoxというものが必要となります。

入手可能なBoxの一覧はこちらから確認できます。

取得したいBoxのURLが分かったらvagrant box addコマンドを利用してBoxを取得します。ざっくりの書式は以下の通りです。

vagrant box add {title} {url}

詳細を知りたいときはvagrant box add -hで調べて下さい。

titleにはvagrantで保存するBoxの名称を記載します。例えばcentos6_4という名称でBoxを保存したい場合は以下のようなコマンドを実行します。

$vagrant box add centos6_4 http://developer.nrel.gov/downloads/vagrant-boxes/CentOS-6.4-x86_64-v20130731.box

ダウンロード完了後、vagrant box listコマンドを使ってBoxの取得が出来ているか確認します。

$vagrant box list
centos6_4 (virtualbox)

上記のようになっていればダウンロードが完了しております。なお、Boxファイルの実態は~.vagrant.d/boxesにあります。

3. 仮想環境のCentOSの作成、起動

準備が出来たのでいよいよCentOSの仮想マシンを作成します。

適当な場所にVagrant用のフォルダを作成し、移動します。

$mkdir -p ~/vagrant/centos64/
$cd ~/vagrant/centos64/

上記の場所でvagrant initコマンドを実行し、仮想環境で利用するBoxを指定します。 先ほどダウンロードしたcentos6.4という名称のBoxを利用する場合には以下のコマンドとなります。

$vagrant init centos6_4

上記を実行するとカレントディレクトリにVagrantfileというものが作成されます。

中身を見ると分かりますが、このファイルの中で利用するBoxを何にするか記載してあります。

config.vm.box = "centos6_4"

また、その他仮想環境に関する設定情報などが本ファイルに記載してあります。

ちょっと話が逸れましたが、次にVMを起動します。 カレントディレクトリにVagrantfileがある場所で以下のコマンドを実施します。

$vagrant up

少し時間が経つとVMが起動したことが分かります。

起動後、以下のコマンドでSSHログインが可能です。

$vagrant ssh

上記でvagrantユーザーでログインができます。簡単ですねー。

その他VMを操作するコマンドとしてはよく利用するのは、シャットダウンさせるvagrant halt、中断させるvagrant suspend、また再会のvagrant resume、環境を破棄するvagrant destory、Vagrantfileの変更を再読みするvagrant reloadあたりでしょうか。詳細やその他コマンドは公式ドキュメントVagrant Documentを見て下さい。

4. 仮想環境にプライベートIPアドレスを設定する

GitリポジトリをVagrant上に作成してアクセスしたいのでVagrant環境に任意のプライベートIPアドレスを指定したいです。

上記の方法は簡単でVagrantfileを編集すればOKです。

#config.vm.network :private_network, ip: "192.168.33.10"

という記述が27行目当たりにあるのでコメントアウトを外します。

config.vm.network :private_network, ip: "192.168.33.10"

上記実施後、Vagrantfileを再読みさせたいのでvagrant reloadコマンドを利用します。

$vagrant reload

とするとVagrantfileが再読み込みされ、VMが再起動します。

vagrant sshしてifconfigコマンドなどを利用するとIPアドレスが設定されているか確認できるかと思います。

上記を利用して例えばvagrant上にapacheを立てて、ホストからhttp://192.168.33.10などでアクセスも可能です。(iptablesを設定している時は解除が必要な場合があります)

なお、Vagrantfileが存在するディレクトリとVMの/vagrant/配下は共有フォルダになっているのでファイルの受け渡しはこちらを利用すると便利です。

5. 仮想環境にGitのリモートリポジトリ作成

基本的な設定は終わったのでVagrantのCentOS6.4にGitのリモートリポジトリの環境を作ります。

と言っても普通に作ってはVagrantでも意味ないよね、という事でVagrantの起動時に自動的にソフトウェアなどをインストールするProvisioing機能を使ってGitリモート環境を作ってみます。(ChefやPuppetとも連携できるみたいですが使った事ないので残念ながら今回はシェルで。。。)

という事でやりかたですが、起動時にシェルを実行する場合にはVagrantfileに以下のような記述を追記します。

config.vm.provision "shell", path: "provision.sh"

上記のような記述をするとカレントディレクトリに存在するprovision.shをvagrant upした時に実行してくれます。

という事で起動と同時にリポジトリを作るシェルを作成してみました。

# install git
sudo yum -y install git

# create git group
sudo groupadd git

# add git group
sudo usermod -a -G git vagrant

# create git repository
sudo mkdir -p /var/public_git/.test.git
sudo git init --bare --shared /var/public_git/test.git
sudo chown -R root:git /var/public_git

少し、説明を記載します。

  • 2行目でGitをインストール
  • 5行目でGit用のgitグループを作成
  • 8行目でvagrantユーザー(sshでログインするユーザー)にgitグループを追加
  • 11行目でGit用のフォルダの/var/public_git/test.gitを作成
  • 12行目で作成したフォルダに共有リポジトリを作成
  • 13行目で作成したフォルダのグループをgitグループに変更

上記によってgitグループのユーザーはcloneが出来るようになります。

試しにホストのMacからgitグループとなっているvagrantユーザーでcloneしてみます。

下記コマンドを実行するとvagrantユーザーのパスワードが聞かれるのでパスワードのvagrantと入力するとcloneが成功する事が確認できます。

$git clone ssh://vagrant@192.168.33.10/var/public_git/test.git
Cloning into 'test'...
vagrant@192.168.33.10's password: 
warning: You appear to have cloned an empty repository.
Checking connectivity... done

また、試しにpushもしてみます。

$cd test
$touch abc.txt
$git add abc.txt
$git commit -m "First Commit"
$git push origin master

ついでにgit用のユーザーを追加して確認してみます。

$vagrant ssh
# 以降仮想環境での操作
$sudo useradd git_user -g git
$sudo passwd git_user
$exit

では追加したユーザー(git_user)で適当なディレクトリに移動し、cloneしてみます。

$git clone ssh://git_user@192.168.33.10/var/public_git/test.git

先ほどpushしたabc.txtも確認できます。

まとめ

上記のように一度シェルを作ってしまえば、例えば設定を誤ってしまった時も

$vagrant destroy
$vagrant up

とすればまた同じ環境が手に入るので便利です。複製も何個でも出来ますし、便利。

Vagrantは単語は知っていたのですが、そんなに学習コスト高くない割に恩恵が大きい気がします。 今後時間あるときはChefも勉強してみてもっと俺俺レシピを作りたいです!

参考サイト