Git/GitHubについて

Gitを使うと,プログラムを書いたり文書を書いたりするとき,更新履歴を残しておくことで,必要に応じて古いバージョンに戻したりできます。また,その作成中のプログラムや履歴をクラウド上に保存して共有することで,共同開発が容易になります。GitやGitHubはこのようなバージョン管理に基づくソースコードの共同開発のためのシステムです。

Gitの基本用語

  • Gitとは: Gitは開発中のソースファイルや作成中の文書のバージョン管理システム。もともとはソースコードの共同開発用に作られたもの。
  • Gitサーバ: リポジトリを一元管理するサーバ。無料サーバとして有名なのにGitHubBitbucketがある。
  • リポジトリ: Gitで管理するソースファイルやそのバージョン情報の置き場所のこと
    • ローカルリポジトリ: 手元のマシン上にあるリポジトリ
    • リモートリポジトリ: Gitサーバ上にあるリポジトリ
  • GitHub Education: GitHubの無料アカウントは,非公開リポジトリ(private repository, アクセス制限つきのリポジトリ)は作れない。しかし,GitHub Educationに教員や学生が申請すると非公開リポジトリを作れるようになる。特に学生が申請した場合にはAWS(Amazon Web Service)の利用クレジットがもらえたり,Microsoft Azureのクラウドサービスが使えたり等々,データサイエンスのお勉強をするための素敵なおまけをたくさんもらえる。

githubを使う準備

習うより慣れよで,使ってみましょう。

準備1: アカウント作り

GitHubBitbucketにアカウントを作る。これは各webページで。とりあえずはGitHubに無料アカウントを作りましょう。

準備2: git コマンドのインストール

git コマンドをローカルマシンにインストールする。 Mac OSの場合は,Xcode コマンドラインツールをインストールしていたら,gitコマンドもインストールされている。Linuxの場合,apt-get対応のディストリビューションなら

$ apt-get install git

で大抵OK。

準備3: 自分のアカウント情報のローカルマシンへの登録

$ git config —global user.name “あなたの名前”
$ git config —global user.name “あなたのメールアドレス”
$ git config —global core.editor vi      # コメント編集に使いたいエディタを設定(デフォルトはvi)

--globalは,すべてのリポジトリに対するデフォルト設定にするためのオプション。 特定のリポジトリでのみ別の設定にしたいときには,以下の準備3でダウンロードしたポジトリ内に移動してから--localを指定して実行する。

リモートリポジトリのダウンロード

誰かが作ったリポジトリをダウンロードして使うには以下のようにする。

1. リポジトリのダウンロード

GitHubにあるリモートリポジトリをhttps接続でダウンロードする場合は以下のコマンドで。(ただし,GitHub上のリポジトリ設定で若干異なる場合もある)

$ git clone https://github.com/someone/somerepo.git

上記URLのsomeone, someprepoの部分はダウンロードしたいリポジトリによって変わる。 例えば,私が作っているC/C++用グラフィックライブラリなら以下のようにダウンロードする。

$ git clone https://github.com/jnishii/jgr.git

ただし,private repository(一般には非公開のリポジトリ)の場合には,以下のようにGitHubのアカウント情報を加える。

$ git clone https://<username>:<password>@github.com/someone/somerepo.git

2. 最新情報のダウンロード/更新ファイルのアップロード

ダウンロードしたファイルをいじるときには,まず,Gitサーバから最新バージョンをダウンロードしてから開始。

$ git pull origin master  

これはサーバ(origin)から,masterブランチ(ブランチは後述)をダウンロードするという意味。

ファイルを更新したら,gitサーバ(origin)にアップロードする。

$ git add <更新したファイル名>
$ git commit -m “修正点を少し書く”            <=ローカルリポジトリ(手元)に登録
$ git push origin master                               <=リモートリポジトリに反映  

とりあえず,これで最低限のファイル共有/共同編集はできる。 git addは,更新したファイルのうち,リモートリポジトリに反映したいファイルを指定(stagingとよぶ。これにより対象ファイルはstaging areaに移動)する。指定方法は以下のようにいろいろある。

  • git add . 新規作成ファイルと更新ファイルを全部指定
  • git add -u 前回から更新したファイルのみ指定(新規作成ファイルは含まない)
  • git add -A .新規作成ファイル,更新ファイル,削除ファイル全部指定

関連コマンド:

  • git reset <ファイル名> 間違えてgit addしたファイルの取り消し(stagingの取り消し)
  • git status 現在のファイルの状態(staging等)一覧を表示する

リポジトリ登録の方法

自分の作ったソースコードをリポジトリ登録して,Git/GitHubで管理する方法

1. プロジェクトをローカルリポジトリに登録

管理したいソースプログラム群があるディレクトリに移動して,バージョン管理のための初期化をする。

$ cd <target directory>
$ git init

これで,バージョン情報を格納する .git/ が作られる。

2. バージョン管理するファイル/ディレクトリを登録

バージョン管理したいファイル/ディレクトリ名を指定する。

$ git add .            # 現在のディレクトリにある全てのファイル/ディレクトリを登録
$ git add figures/     # ディレクトリ figures/ 以下のファイルを登録
$ git add *.tex        # すべての .tex ファイルを登録

3. ファイルの内容を初期登録

$ git commit -m "はじめてのgit"`

-mは1行コメントをつけるオプション。初期化のときに限らず,新く作ったファイルを登録するときには,git addgit commitを随時実行。ここまではローカルリポジトリ(ローカルマシン上のリポジトリ)のみの設定。

4. Gitサーバに登録する

インターネット上のどこからでも最新ファイルを入手できるようにするには,Gitサーバにリポジトリを登録する。

  1. git サーバ上に新規リポジトリを作る(GitHubやBitbucketの各webページ上で作る)
  2. ローカルリポジトリ(要はgit管理したいプログラム群のあるディレクトリ)をgitサーバ(公開リポジトリ)に登録する。以下はGitHubに登録する例

    $ cd <directory> <= 登録したいファイル群のあるディレクトリ
    $ git remote add origin https://github.com/someone/someprepo.git

    これで,サーバにファイル置き場(リポジトリ)が作られる。origin と記載している部分は,このリポジトリ(git@github….git)に対する短縮名。オリジナルなソースコードを登録するときには origin とする事が多いが,別に他の名前にしても良い。someone/somerepoの部分は,GitHub上に作ったリポジトリの名前に従って設定する。

    非公開リポジトリ(private repository)に登録する場合は,以下のようにGitHubの認証情報を加える。

    $ git remote add origin https://<username>:<password>@github.com/someone/somerepo.git

    ただ,パスワード情報等を平文打ちして保存するのはセキュリティ上よろしくはないので,ssh keyをGitHubに登録しておいて,ssh通信にするほうが無難。

    $ git remote add origin git@github.com:someone/somerepo.git
  3. 登録情報を確認

    $ git remote -v

    登録情報を間違えていたら,以下のコマンドで一旦削除して再登録する

    $ git remote rm origin
  4. リモートリポジトリにファイルをアップロード

    $ git push -u origin master  

使う!

以下のgitコマンドは,ローカルリポジトリ(手元のディレクトリ)内のみの変更。サーバへの更新やサーバからのダウンロードのため,毎日の更新前にはgit pull, 更新後にはgit pullを使うこと。

  • ファイルの変更情報をgitに登録

    $ git commit -a -m "ファイル変更"`

    オプション

    • -a 変更されたファイルすべてを対象とする(git add -uと同じ)
    • -mはコメント(メッセージ)をつける。省略するとviが起動して,長いコメントを入れられる。
  • 履歴をみる

    $ git log  
    commit 989d476c5ab7fb30bb0eb1ca8f5b917860c9c719`
    Author: jun nishii
    Date:   Wed May 24 13:22:45 2017 +0900  
    First commit  
  • 最新ファイル(最後にcommitしたもの)と,あるバージョンの比較をしたいとき

    $ git show 989d476c5ab7fb30bb0eb1ca8f5b917860c9c719 --word-diff=color  
  • あるバージョンに戻したい時

    $ git checkout 989d476c5ab7fb30bb0eb1ca8f5b917860c9c719 *  

    ただし,戻したバージョンを最終バージョンにしたいときには,ここでcommitする。(さらにファイルを修正後でももちろんOK)

    $ git commit -a -m "バージョンを戻す"
  • あるバージョンでアブストラクトを書いて,次のバージョンで序論を修正,さらに次のバージョンで図を加えたとする。その後,序論の修正に後悔して,序論のみをもとに戻したくなったとき。(特定の修正を取り消したい時)

    $ git revert <序論を修正したバージョンのID>
  • commitした後に,少し修正して,さっきのcommitとまとめてしまいたいとき

    $ git commit --amend
  • 現在のディレクトリにファイルにcommitしていないのがあるかを確認する

    $ git status

    このときgitコマンドでは無視したいファイルが有る時(LaTeXの一時ファイル等)は,.gitignoreという名前のファイルをローカルリポジトリ内に作っておく。

    $ cat .gitignore
    *.aux
    *.idx
    *.log
    *.toc
    *.ist
    *.bbl
    *.blg
    *.dvi
    *.ilg
    *.ind
    *.lot
    *.out
    *.synctex.gz
  • gitに登録したファイルやディレクトリを消したい時

    $ git rm <file>   or git rm -r <directory>
  • gitに登録したファイルやディレクトリの名前を変える

    $ git mv <old name> <new name>

いろいろなコマンド

毎日の作業前には最新情報のダウンロードのためのgit pull, 更新後にはサーバへのアップグレード(リモートリポジトリへの登録)のためにgit pullを忘れずにすること。以下はコマンド例

$ git pull origin master # サーバoriginのmasterブランチから最新情報取得
$ git push origin master # サーバoriginのmasterブランチに更新情報反映

ローカルリポジトリの操作

以下のgitコマンドは,ローカルリポジトリ(手元のディレクトリ)内のみの変更をする。 変更後には上記のgit pushを忘れずに。

  • ファイルの変更情報をgitに登録

    $ git commit -a -m "ファイル変更"`

    オプション

    • -a 変更されたファイルすべてを対象とする(git add -uと同じ)
    • -mはコメント(メッセージ)をつける。省略するとviが起動して,長いコメントを入れられる。
  • 履歴をみる

    $ git log  
    commit 989d476c5ab7fb30bb0eb1ca8f5b917860c9c719`
    Author: Jun Nishii
    Date:   Wed May 24 13:22:45 2017 +0900  
    First commit  
  • git -addの取り消し(stagingの取り消し)
    $ git reset HEAD <file name>

    staging状態にあるファイル全てについて取り消す時にはファル名の指定は無しで。

  • 最新ファイル(最後にcommitしたもの)と,あるバージョンの比較をしたいとき

    $ git show 989d476c5ab7fb30bb0eb1ca8f5b917860c9c719 --word-diff=color  
  • あるバージョンに戻したい時

    $ git checkout 989d476c5ab7fb30bb0eb1ca8f5b917860c9c719 *  

    ただし,戻したバージョンを最終バージョンにしたいときには,ここでcommitする。(さらにファイルを修正後でももちろんOK)

    $ git commit -a -m "バージョンを戻す"
  • あるバージョンでアブストラクトを書いて,次のバージョンで序論を修正,さらに次のバージョンで図を加えたとする。その後,序論の修正に後悔して,序論のみをもとに戻したくなったとき。(特定の修正を取り消したい時)

    $ git revert \<序論を修正したバージョンのID\>
  • commitした後に,少し修正して,さっきのcommitとまとめてしまいたいとき

    $ git commit --amend
  • 現在のディレクトリにファイルにcommitしていないのがあるかを確認する

    $ git status

    このときgitコマンドでは無視したいファイルが有る時(LaTeXの一時ファイル等)は,.gitignoreという名前のファイルをローカルリポジトリ内に作っておく。

    $ cat .gitignore
    *.aux
    *.idx
    *.log
    *.toc
    *.ist
    *.bbl
    *.blg
    *.dvi
    *.ilg
    *.ind
    *.lot
    *.out
    *.synctex.gz
  • gitに登録したファイルやディレクトリを消したい時

    $ git rm \<file\>   or git rm -r \<directory\>
  • gitに登録したファイルやディレクトリの名前を変える

    $ git mv \<old name\> \<new name\>

ブランチ

リポジトリをダウンロード(git clone)し,一時的に自分なりのカスタマイズをしたり,開発用のテスト版を作りたいときには,派生バージョン(branch)を作って管理できる。

派生バージョン(branch)の作成

  1. git cloneでリポジトリのダウンロード
  2. ブランチを作る。例えば,branch名を test にする場合は以下の通り。
    $ git checkout -b test

どのbranchを編集するか変更

リポジトリ内で,複数のbranchの編集が可能。その切替は以下のコマンドで

  1. 現在,どのbranchを編集可能か確認
    $ git branch

    サーバ上のブランチもすべて見たいときには-aをつける

  2. test branchを編集したいときには
    $ git checkout test
  3. 作業branchが変わったことを確認
    $ git branch

branchを,もとのバージョンに反映したい時

作ったtestブランチを,サーバ上にも反映する。

$ git push -u origin test

-uは新規ブランチを始めてサーバにアップロードする時につける。2回目以降は省略可

変更を一時的に隠す

修正中の手元のファイルは一旦退避して(隠して),GitHub上のファイルをpullしたいときにはstash (「隠す」の意味)を使う。

変更を隠す(退避)

  • commitしていない変更部分を退避する。
    $ git stash save

    これで,現在編集中のbranchの全ての変更は一時キャンセルさせて状態になる。 git add によるstagingの有無に関係なく退避されますが,新規追加したファイルは退避されない。

  • 新規追加したファイルも退避する
    $ git stash -u save

    -u--include-untrackedでもOK。

  • addした変更以外を退避する
    $ git stash -k
  • 退避時にメッセージを付ける
    $ git stash save "some message..."

退避している変更の情報を表示する

  • 退避している変更の一覧を表示する。
    $ git stash list

    これで,退避した変更のID(stash@{0}等)やメッセージが表示される。

  • 退避した変更に含まれるファイル一覧を表示
    $ git stash show <ID>
  • 変更内容の詳細を表示
    $ git stash show <ID> -p

退避したファイルを戻したり消したりする

  • 退避していた変更を戻す
    $ git stash apply <ID>
  • 退避していた変更を戻し,stashのリストからも消す
    $ git stash pop <ID>
  • 退避していた変更を消す
    $ git stash drop <ID>
  • 退避していた変更を全て消す
    $ git stash claer

トラブル

困ったときの対応集

Q. origin に設定しているリモートリポジトリURLを変更したい。

originに設定しているリポジトリの接続先をhttpsにしていたが,やっぱりssh接続にした いとか,リモートリポジトリのURLが変更になったときには,以下のようにoriginの設定を変更する。

$ git remote set-url origin <new repository>

Q. remote: Repository not found

git cloneをしたらremote: Repository not found と言われた。

A. private repository (非公開のリポジトリ)からgit cloneしようとするとこのエラーが出る。

もしくは,sshでgit cloneする。

$ git clone git@github.com/someone/somerepo.git

もしくは,(セキュリティ上あまり勧めないが),以下のように認証情報を加えてgit cloneをする。

$ git clone https://<username>:<password>@github.com/someone/somerepo.git

Q. fatal: unable to access

git pushfatal: unable to access 'https://github.com/someone/somerepo.git': The requested URL returned error: 403と言われた。

A. remote repository の URLにユーザ名を加えたら治った。

$ git remote set-url origin https://<user name>@github.com/someone/somerepo.git

Q. fatal: refusing to merge unrelated histories

git pullをしたら

* branch            master     -\> FETCH_HEAD
    fatal: refusing to merge unrelated histories

と言われた。

A. 以下を試す。

$ git merge --allow-unrelated-histories origin/master