02_Git

この記事は,情報セキュリティ･スキルアッププロジェクト introフェーズ向けのハンズオンとして作成されました.

# ハンズオン
## 0. 準備
### 0.1 gitがインストールされているか再度確認.
```
$ git --version
[ex]>> git version 2.32.1
```
バージョンが表示されればひとまずOK.
### 0.2 設定の確認
```
$ git config --list
```
`user.name`､` user.email`が設定してあればokです｡設定がされていた人は､0.4に進んでください｡
なにか表示されるので,ひとまず`q`を押して戻る.
### 0.3 設定
**ユーザー名**と**メールアドレス**を登録する.
```
$ git config --global user.name "{ユーザー名}"
$ git config --global user.email "{メールアドレス}"
```
::: note 
`{ユーザー名}`,`{メールアドレス}`には,それぞれ自分のユーザー名とメールアドレスを入力します.
`{}`は不要ですが,`""`(ダブルクオーテーション)で囲む必要があります.
:::
もう一度設定を確認.
```
$ git config --list
```

```
user.name='hoge'
user.email='hoge@example.com'
```
と表示されればOK.`q`を押して抜け出す.

::: note 
設定した情報は,`~/.gitconfig`に格納されています.
確認してみましょう.(hint: `cat`コマンドを使う)
<details><summary>こたえ</summary>

```
$ cat ~/.gitconfig
```
</details>
:::
### 0.4 Githubにアクセスする準備をしよう
> gitではネットワークのプロトコルとしてHTTPSとSSH(Secure Shell)を利用することができます.[^1]

このセクションでは,
①SSHキーを作って> ②公開するところまでを行います.
### 0.4.1 SSH鍵を作成する.

まずは①SSH鍵を作るところです.

::: note
**鍵について**
ここで作成するのは｢公開鍵｣と｢秘密鍵｣です.
ざっくりいうと,｢**公開鍵**｣ は **施錠**用の鍵, ｢**秘密鍵**｣は **解錠**用の鍵です.公開鍵をGithubに登録します.秘密鍵は,
  **絶対に公開しないでください**.
:::
鍵が作成されているか確認.すでに鍵が存在していた場合は,`0.4.2`に進んでください. 
```
$ ls ~/.ssh
```
例えば, `id_rsa`, `id_rsa.pub`があればOKです.

ない場合は,以下の手順を進めてください.
```:鍵を生成する
$ ssh-keygen
```
このあと諸々の質問をされますが,今回はEnterキーを押して続けます.
(パスフレーズを求められますが,入力しなくても問題ありません.ここはおまかせします.)
全て済むと,鍵が生成されます.
もう一度
```
$ ls ~/.ssh
```
を実行して,`id_rsa`, `id_rsa.pub`ができているか確認します.

続いて,公開鍵をコピーします.
```:公開鍵を出力
$ cat ~/.ssh/id_rsa.pub
```
で公開鍵を表示させ,出力された内容すべてをコピーします

### 0.4.2 SSH鍵をGitHubに登録
続いて②の公開するところです.
[github](https://github.com)を開きます.
![Screenshot 2022-08-16 at 02-10-40 ikedaryo8 - Overview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2697677/7306b3ba-93fe-db6b-541a-8e67275761c3.png)
![Screenshot 2022-08-16 at 02-13-12 Build software better together.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2697677/c4508cba-c563-9b6d-b98f-e8dbaaf71f81.png)
![Screenshot 2022-08-16 at 02-14-40 Add new SSH keys.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2697677/ffad8f34-49fd-bf3d-87ff-d48a6f03f9c0.png)

これで準備はだいたいOK.あとは必要に応じてカスタマイズしていこう.
---
## 1. 基本操作 ローカル
### 1.1 git操作 基本の流れ


<details><summary>作業用のディレクトリを作っておくといい
</summary>

```
$ mkdir ~/hoge/git_practice/
```
*ファイル名は任意.
また,ファイルを残したくないときは,
`/tmp/`で作業をするよい.再起動すると消える.

--- 
</details>

#### 1.1.1 [リポジトリ](#用語辞典)を作成する.

```
$ git init
```
を実行すると,`.git`ディレクトリが作られる.隠しファイルなので,`$ ls -a`で確認してみよう.
次に
```
$ git status
```
を実行.これで現在のリポジトリの状態を確認できる.
<details>
<summary>例</summary>

```:
On branch main

No commits yet

nothing to commit (create/copy files and use "git add" to track)
```
--- 
</details>

ここで適当なファイルを作成

<details><summary>例
</summary>

```:foo.py
x = input("x: ")
y = input("y: ")
print(x+y)
```
--- 
</details>

もう一度
```$ git status```
 を実行してみよう.(表示が変わる)

<details>
<summary>実行結果 例</summary>

```:
On branch main

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	foo.py

nothing added to commit but untracked files presentnt (use "git add" to track)
```
--- 
</details>

#### 1.1.2 ステージングする
```
$ git add foo.py
// ディレクトリまるごと
// $ git add .
```
もう一度
```$ git status```
 を実行してみよう.(また表示が変わる)

<details>
<summary>実行結果 例</summary>

```:
On branch main

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
	new file:   foo.py

```
--- 
</details>



#### 1.1.3 コミットする.
```
$ git commmit -m "{コミットメッセージ}" 
```
`-m`オプション ではコミットメッセージを指定する.これをつけないと,エディタが立ち上がり,コミットメッセージを求められる.

コミットメッセージについて
コミットメッセージは,｢自分が何を意図してファイルを編集したか｣を残すことができる.後で見返したときに,役立つので積極的に活用しよう.
> 1週間前の自分は他人.1週間後の自分も他人.

### 1.2 ファイルの変更の記録
ここで作成したプログラムを実行してみましょう.
```
>> python foo.py
x: 10
y: 20
1020
```
標準入力受け取った入力を,`str`型のまま変数に格納していたため,文字列の連結してしまっています.
ここで,`foo.py`を編集します.
```diff:foo.py
+ 1| x = int(input("x: "))
+ 2| y = int(input("y: "))
  3| print(x+y)
```
```$ git status```
 を実行してみよう.

<details>
<summary>実行結果 例</summary>

```:
On branch main

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
	new file:   foo.py

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   foo.py
```
--- 
</details>

#### 1.2.1 差分の表示
変更した部分を表示する.
```
$ git diff
```
<details><summary> 実行結果 例 </summary>

![スクリーンショット 2022-10-10 23.13.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2697677/927bc36b-dd64-aab1-47d9-3026a8ddccb9.png)
</details>
変更された部分が色分けして表示される.

ステージングすると,`git diff`すると差分表示はされなくなる.

<details><summary>ステージング & コミットまで</summary>

```
$ git add foo.py
$ git commit -m "標準入力からの受け取りを`int`型に変換して,足し算できるようにする.1."
```
</details>

#### 1.2.2 変更履歴の確認
変更してきた履歴は,
```
$ git log
```
コマンドで確認できる.

### 1.3 変更の取り消し 
[[参考]](https://www-creators.com/archives/1290)こちらにきれいにまとまっているので,詳しくはこちらを見てください.
#### 1.3.1 ステージング前の変更を取り消す
```
$ git checkout {ファイル名など}
```
```
$ git checkout foo.py 
```
#### 1.3.2 ステージ済/未コミットの変更を取り消す
``` 
$ git checkout HEAD {ファイル名など}
```
#### 1.3.3 コミット済の変更を取り消す
```:直前の変更を打ち消す"コミット"を作成
$ git revert HEAD
```


### 1.4 ブランチを使う
#### 1.4.1 ブランチの基本操作
```:ブランチを確認する
$ git branch
```

```:ブランチの作成
// git brahch {ブランチ名}
$ git branch b1
```
```:ブランチの移動
$ git switch b1
```
<details> <summary> 作成&移動を一括で </summary>
```ブランチ作成&移動
$ git switch -c b1
``` 
</details>

#### 1.4.2 ブランチ上での開発
1. `b1`ブランチ上でファイルを変更する｡
    <details> <summary>例</summary>
    
    ```diff:foo.py
    + 3 | print("x + y = " = str(x+y))
    ```
    </details>

2. 変更出来たら､ `b1`ブランチ上でコミットする.
3. `main`ブランチへ戻る
    <details> <summary>`main`ブランチに戻る.</summary>
    ```
    $ git switch main
    ```    
    </details>

4. 編集したファイルを確認する.
    ファイルが変更されていない!!

5. 編集を`merge`(マージ)する
```
$ git merge b1
```

<details> <summary> 実行結果 </summary>
```
Updating fbe916b..bf01857
Fast-forward
 foo.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
```
</details>

<details><summary>`git log`してみる</summary>

![スクリーンショット 2022-10-11 1.15.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2697677/7d0cb99a-ef58-7cd3-ecf8-830b2d42d1b0.png)
</details>


## 2 基本操作 リモートリポジトリ(編集中)



### 2.1 既存のリモートリポジトリを`clone`して使う
[本日のリポジトリ](https://github.com/kit-SecurityPRJ/git-tutorial-2022)

1. リポジトリの作成
![スクリーンショット 2022-10-12 8.21.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2697677/69475822-9287-e78e-ca36-79fab05821ad.png)
![スクリーンショット 2022-10-12 12.36.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2697677/13700acb-b1de-e4c5-4ce1-b520d9dfee3e.png)
![スクリーンショット 2022-10-12 8.14.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2697677/ac131b69-68ba-df7f-5340-ad220d866ebf.png)
    ```
    echo "# git-tutorial" >> README.md
    git init
    git add README.md
    git commit -m "first commit"
    git branch -M main
    git remote add origin git@github.com:ikedaryo8/git-tutorial.git
    git push -u origin main
    ```
2. リポジトリの紐付け
    ```:リモートリポジトリのコピーを作成
    $ git clone {コピーしたURL}
    ```
    ```:既存のディレクトリにに結びつける場合
    $ git remote add origin git@github.com:ikedaryo8/git-tutorial.git
    ```
3. 編集等...
4. リモートリポジトリにプッシュする
    ```
    $ git push -u origin main
    ```


# 用語辞典
|言葉||説明|
|---|---|---|
|リポジトリ||(gitの管理下にある)ファイルやディレクトリを溜めて置く場所.|
|ディレクトリ||フォルダに同義|
|ファイル||`txt`などのデータのまとまり|
|クローン|`git clone {リポジトリのアドレス}`|リポジトリのコピーを作成|
|フォーク||GitHubの独自機能.GitHub上でのクローン|
||||
|ステージング|`git add {ファイル名}`|
||||
||||
---
[^1]: 井上 顧基, (2022)｢Git入門コマンドライン演習80｣,p58.
[^key]: a