Visual Studio Code の git 連携機能と git コマンドについて (2018/05/23)

# Visual Studio Code の git 連携機能と git コマンドについて (2018/05/23)

> [Git - Book 2nd Edition (2014)](https://git-scm.com/book/ja/v2) 日本語訳の
>
> * [Chapter 2. Git の基本](https://git-scm.com/book/ja/v2/Git-の基本-Git-リポジトリの取得)
> * [Chapter 3. Git ブランチ機能](https://git-scm.com/book/ja/v2/Git-のブランチ機能-ブランチとは)
> * [Chapter 7. Git のさまざまなツール](https://git-scm.com/book/ja/v2/Git-のさまざまなツール-リビジョンの選択)
>
> に出てくるコマンドに VS Code のコマンドをあてる感じで書き直してみる
 
<!-- TOC -->

- [Visual Studio Code の git 連携機能と git コマンドについて (2018/05/23)](#visual-studio-code-の-git-連携機能と-git-コマンドについて-20180523)
    - [Git の情報源](#git-の情報源)
    - [Git クライアントとしての Visual Studio Code](#git-クライアントとしての-visual-studio-code)
    - [git コマンドと vscode の git 関連操作](#git-コマンドと-vscode-の-git-関連操作)
        - [git 連携機能の設定項目](#git-連携機能の設定項目)
        - [出力パネル](#出力パネル)
    - [Git の基本](#git-の基本)
        - [Git リポジトリの取得](#git-リポジトリの取得)
            - [既存のディレクトリでのリポジトリの初期化](#既存のディレクトリでのリポジトリの初期化)
            - [既存のリポジトリのクローン](#既存のリポジトリのクローン)
        - [変更内容のリポジトリへの記録](#変更内容のリポジトリへの記録)
            - [ファイルの状態の確認](#ファイルの状態の確認)
            - [新しいファイルの追跡と変更したファイルのステージング](#新しいファイルの追跡と変更したファイルのステージング)
            - [状態表示の簡略化](#状態表示の簡略化)
            - [ファイルの無視](#ファイルの無視)
            - [ステージされている変更/されていない変更の閲覧](#ステージされている変更されていない変更の閲覧)
            - [変更のコミット](#変更のコミット)
            - [コミットメッセージについて](#コミットメッセージについて)
                - [commit message のテンプレート](#commit-message-のテンプレート)
            - [ステージングエリアの省略](#ステージングエリアの省略)
            - [ファイルの削除](#ファイルの削除)
            - [ファイルの移動](#ファイルの移動)
        - [コミット履歴の閲覧](#コミット履歴の閲覧)
        - [作業のやり直し](#作業のやり直し)
            - [ステージしたファイルの取り消し:](#ステージしたファイルの取り消し)
            - [ファイルへの変更の取り消し](#ファイルへの変更の取り消し)
            - [コミットの取り消し](#コミットの取り消し)
            - [VS Code の "すべての変更を破棄" について](#vs-code-の-すべての変更を破棄-について)
        - [リモートでの作業](#リモートでの作業)
            - [リモートの表示](#リモートの表示)
            - [リモートリポジトリの追加](#リモートリポジトリの追加)
            - [リモートからのフェッチ、そしてプル](#リモートからのフェッチそしてプル)
            - [リモートへのプッシュ](#リモートへのプッシュ)
            - [リモートの調査](#リモートの調査)
            - [リモートの削除・リネーム](#リモートの削除・リネーム)
        - [Git の基本 - タグ](#git-の基本---タグ)
    - [Git のブランチ機能 (Chapter 3)](#git-のブランチ機能-chapter-3)
        - [ブランチとは](#ブランチとは)
        - [新しいブランチの作成](#新しいブランチの作成)
        - [ブランチの切り替え](#ブランチの切り替え)
        - [Git のブランチ機能 - ブランチとマージの基本](#git-のブランチ機能---ブランチとマージの基本)
            - [ブランチの基本](#ブランチの基本)
            - [マージの基本](#マージの基本)
            - [マージ時のコンフリクト](#マージ時のコンフリクト)
        - [Git のブランチ機能 - ブランチの管理](#git-のブランチ機能---ブランチの管理)
            - [Git のブランチ機能 - ブランチでの作業の流れ](#git-のブランチ機能---ブランチでの作業の流れ)
            - [Git のブランチ機能 - リモートブランチ](#git-のブランチ機能---リモートブランチ)
            - [プッシュ(リモートブランチへのプッシュ)](#プッシュリモートブランチへのプッシュ)
            - [追跡ブランチ](#追跡ブランチ)
            - [プル](#プル)
            - [リモートブランチの削除](#リモートブランチの削除)
        - [リベース](#リベース)
    - [Git のさまざまなツール (Chapter 7)](#git-のさまざまなツール-chapter-7)
        - [行単位のステージングと取り消し](#行単位のステージングと取り消し)
        - [作業の隠しかたと消しかた](#作業の隠しかたと消しかた)
            - [自分の作業を隠す (git stash)](#自分の作業を隠す-git-stash)
        - [歴史の書き換え](#歴史の書き換え)
            - [直近のコミットの変更](#直近のコミットの変更)
        - [サブモジュール](#サブモジュール)
            - [サブモジュールの作り方](#サブモジュールの作り方)
            - [サブモジュールを含むプロジェクトのクローン](#サブモジュールを含むプロジェクトのクローン)
            - [サブモジュールを含むプロジェクトでの作業](#サブモジュールを含むプロジェクトでの作業)
            - [サブモジュールに加えた変更の公開](#サブモジュールに加えた変更の公開)
        - [変更されたサブモジュールのマージ](#変更されたサブモジュールのマージ)
            - [変更されたサブモジュールのマージ](#変更されたサブモジュールのマージ-1)
    - [綺麗にまとめられないので、ひとまず下記においとく](#綺麗にまとめられないのでひとまず下記においとく)
        - [Added support for encodings for Git.](#added-support-for-encodings-for-git)
    - [外部エディタ/Diff ツール（差分表示ツール）としての Visual Studio Code](#外部エディタdiff-ツール差分表示ツールとしての-visual-studio-code)
    - [あると便利な拡張機能](#あると便利な拡張機能)
        - [Open in SourceTree](#open-in-sourcetree)
        - [Open in Fork](#open-in-fork)
        - [Open in GitHub](#open-in-github)
    - [プライベートな Git リポジトリ](#プライベートな-git-リポジトリ)
    - [Thanks](#thanks)

<!-- /TOC -->


理解できていないので、勉強のためにまとめてみる。

Visual Studio Code (以下、VS Code) の git 連携機能は、VS Code 自身が git 機能を持つ訳ではなく、PATH 上に存在する git コマンドを利用することで実現している。
そのため、VS Code に加えて [Git](https://git-scm.com) を個別にインストールする必要あり。

下記のドキュメントにも記載がありますが、ほかのツールから外部エディタとして Visual Studio Code を呼び出すことを目的とした機能が追加されたため、git `2.0.0` 以降が要件となっている。

* [Git editor and -w / --wait mode for Code #4006](https://github.com/Microsoft/vscode/issues/4006)
* [-w options is not working as expected in Windows git config #4214](https://github.com/Microsoft/vscode/issues/4214)

## Git の情報源

VS Code の git (バージョン管理) については、下記のマニュアルを参考に。

* 英語: [Using Version Control in VS Code](https://code.visualstudio.com/docs/editor/versioncontrol)
* 日本語: [バージョン管理](https://vscode-doc-jp.github.io/docs/userguide/versioncontrol.html)

VS Code の git 連携記事:

* [Visual Studio CodeでGitを利用する (1/4)](http://www.atmarkit.co.jp/ait/articles/1507/21/news017.html)
* [Visual Studio Code for Mac developers: Git](https://blogs.msdn.microsoft.com/cdndevs/2015/10/12/visual-studio-code-for-mac-developers-git/)

git そのものについては、下記で。

* [Git - Reference](https://git-scm.com/docs)
* [Git - Book (日本語版あり, PDF, epub, mobi)](https://git-scm.com/book/ja/v2) 
* [Quick reference guides: GitHub Cheat Sheet ](https://services.github.com/on-demand/downloads/github-git-cheat-sheet.pdf)
* [Git Tutorials and Training](https://www.atlassian.com/ja/git)
* [Atlassian Blogs の Archives for the tag: git](http://japan.blogs.atlassian.com/tag/git/)
* git pull/commi/push の基本的な操作の学習は [Git-it](https://github.com/jlord/git-it-electron) がオススメ。git の基本と GitHub の使い方を手を動かしながら学べ、チュートリアル形式でわかりやすく日本語で解説してくれる Electron アプリケーション。

## Git クライアントとしての Visual Studio Code

コマンドを知らなくても、git リポジトリを操作できる。

もともと、Visual Studio Code では source code control に Git の利用を想定していたが、Source control manager (SCM) の登場により、このあたりはいろいろと変わってきている。
しばらくの間、バージョン管理機能は、git 一択だったけど、VS Code 1.10.0 で [Contributable SCM providers](https://code.visualstudio.com/updates/v1_10#_contributable-scm-providers) と呼ばれるフレームワークに移行し、built-in だった git 連携機能は、SCM を利用する一つの拡張機能として切り出され実装しなおされた。

VS Code 1.11.0 では、[Git extension enabled](https://code.visualstudio.com/updates/v1_11#_git-extension-enabled) として default で SCM が利用されるようになり、様々な機能が追加されてきている。

Git なので、当然だけど、ローカル/リモートリポジトリを利用できる。

## git コマンドと vscode の git 関連操作

ソース管理: GIT ビューで可能な git 操作はこんな感じ (・・・をクリックすると表示されるメニュー)

![スクリーンショット 2017-04-24 0.17.18.png](https://qiita-image-store.s3.amazonaws.com/0/65800/5527b473-44e1-38eb-7990-f6fb55fb710c.png)

SCM プロバイダーの切り替え... では、ソースコード管理に利用するツールを指定できる。標準では Git のみだったが、ついに Mercurial をサポートする拡張機能 [Hg - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=mrcrowl.hg) が登場した。こんな感じで、機能を追加できるように VS Code 1.11 から変更になっている。

* [Visual Studio Code Source Control API](https://code.visualstudio.com/docs/extensionAPI/api-scm)
* [Microsoft/vscode-SCMBuilders](https://github.com/Microsoft/vscode-SCMBuilders) - This is a repo to help the extension builder community create new SCM providers for Visual Studio Code. It contains samples as well as instructions for getting going.

git 連携機能の実装については、下記のソースコードが参考になるかと思います。

- <https://github.com/Microsoft/vscode/blob/master/extensions/git/>

とりあえず、調べている途中のもの。
間違いがあったりはっきりわからない部分がありますが、理解できたものから更新してく。

| git コマンド                | vscode コマンド           | command                    | コマンド                                | バージョン         |
| --------------------------- | ------------------------- | -------------------------- | --------------------------------------- | ------------------ |
| git branch                  | git.branch                | Create Branch...           | 分岐の作成...                           |                    |
| git checkout -q             | git.checkout              | Checkout to...             | チェックアウト先...                     |                    |
| git checkout --             | git.clean                 | Git: Discard Changes       | 変更を破棄                              |                    |
| git clean ?                 | git.cleanAll              | Git: Discard All Changes   | すべての変更を破棄                      |                    |
| git clone                   | git.clone                 | Clone                      | クローン                                    | 1.10               |
| git commit                  | git.commit                | Commit                     | コミット                                |                    |
| git commit -a               | git.commitAll             | Commit All                 | すべてコミット                          |                    |
| git commit -a -s            | git.commitAllSigned       | Commit All (Signed Off)    | すべてコミット (サインオフ)             |                    |
| git commit --amend          | git.commitStaged          | Commit Staged              | ステージング済みをコミット              |                    |
| git commit -s --amend       | git.commitStagedSigned    | Commit Staged (Signed Off) | ステージング済みをコミット (サインオフ) |                    |
|                             | git.commitAllAmend        | Commit All (Amend)         | すべてコミット (修正)                   | ![1.16]            |
|                             | git.commitStagedAmend     | Commit Staged (Amend)      | コミットしてステージング (修正)         | ![1.16]            |
| git tag (-a -m)             | git.createTag             | Create Tag                 | タグを作成                              | ![1.16]            |
|                             | git.pushWithTags          | Push With Tags             | タグをつけてプッシュ                    | ![1.16]            |
| git fetch                   | git.fetch                 | Fetch                      | フェッチ                                | ![1.19]            |
| git stash                   | git.stash                 | Stash                      | スタッシュ                              | ![1.16]            |
| git stash                   | git.stashIncludeUntracked | Stash (Include Untracked)  | スタッシュ (未追跡ファイルを含む)       | ![1.19]            |
| git stash list              | git.stashPop              | Pop Stash                  | スタッシュを適用して削除...             | ![1.16]            |
| git stash apply             | git.stashPopLatest        | Pop Latest Stash           | 最新のスタッシュを適用して削除          | ![1.16]            |
| git branch -d               | git.deleteBranch          | Delete Branch...           | ブランチの削除...                       | ![1.13]            |
|                             | git.ignore                | Add File to .gitignore     | ファイルを .gitignore に追加            | ![1.14]            |
| git init                    | git.init                  | Initialize Repository      | リポジトリの初期化                      | ![1.16]            |
| git merge                   | git.merge                 | Merge Bracnhe...           | ブランチをマージ...                     | ![1.14]            |
|                             | git.openChange            | Open Changes               | 変更を開く                              |                    |
|                             | git.openFile              | Open File                  | ファイルを開く                          |                    |
|                             | git.openHEADFile          | Open File (HEAD)           | HEAD のファイルを開く                   |                    | 
|                             | git.publish               | Publish Branch             | ブランチの発酵                          | 1.13 で変更        |
| git pull                    | git.pull                  | Pull                       | プル                                    |                    |
| git pull                    | git.pullFrom              | Pull (From Remote)         | 指定元からプル                      | ![1.20] で remote branch 表示対応|
| git pull --rebase           | git.pullRebase            | Pull (Rebase)              | プル (リベース)                     |                     |
| git push                    | git.push                  | Push                       | プッシュ                           |                     |
| git push (remote) (branch)  | git.pushTo                | Push to...                 | プッシュ先...                      |                     |
|                             | git.refresh               | Refresh                    | 最新の情報に更新                    |                     |
| git reset -p                | git.revertSelectedRanges  | Revert Selected Ranges     | 選択範囲を元に戻す                  |                     |
| git add                     | git.stage                 | Stage Changes              | 変更のステージング                  |                     |
| git add -A --               | git.stageAll              | Stage All Changes          | すべての変更のステージング           |                    |
| git add -p                  | git.stageSelectedRanges   | Stage Selected Ranges      | 選択した範囲をステージする           | ![1.10]             |
|                             | git.stageChange           | Stage Change               | 変更のステージング                  |                    |
|                             | git.revertChange          | Revert Change              | 変更を元に戻す                     |                     |
| git pull して必要であれば push してる？ | git.sync           | Sync                      | 同期                             |                     |
| git pull して必要であれば push してる？ | git.syncRebase     | Sync (Rebase)              | 同期 (リベース)                   |                     |
| git reset --hard HEAD^      | git.undoCommit            | Undo Last Commit           | 前回のコミットを元に戻す             |                      |
| git revert                  | git.unstage               | Unstage Changes            | 変更のステージング解除              |                    |
| git revert ?                | git.unstageAll            | Unstage All Changes        | すべての変更のステージング解除        |                    |
|                             | git.unstageSelectedRanges | Unstage Selected Ranges    | 選択した範囲をアンステージする        |                     |
| 内部コマンド                  | git.commitWithInput       |                            |                                 |                   |
| 内部コマンド                  | git.openResource          |                            |                                  |                     |
| 内部コマンド                  | git.showOutput            |                            |                                  |                    |
| 内部コマンド                  | git.close                 |                            | リポジトリを閉じる                  | ![1.19]             |


[1.20]: https://img.shields.io/badge/vscode-1.20-green.svg
[1.19]: https://img.shields.io/badge/vscode-1.19-blue.svg
[1.18]: https://img.shields.io/badge/vscode-1.18-blue.svg
[1.17]: https://img.shields.io/badge/vscode-1.17-orange.svg
[1.16]: https://img.shields.io/badge/vscode-1.16-orange.svg
[1.15]: https://img.shields.io/badge/vscode-1.15-green.svg
[1.14]: https://img.shields.io/badge/vscode-1.14-green.svg
[1.13]: https://img.shields.io/badge/vscode-1.13-green.svg
[1.10]: https://img.shields.io/badge/vscode-1.10-green.svg


[5f31035]:https://github.com/Microsoft/vscode/commit/5f31035e46a69b5f0f91dd13a3dce8bfc26f0801
[git.sync]: https://github.com/Microsoft/vscode/blob/master/extensions/git/src/commands.ts#L708
[git.publish]: https://github.com/Microsoft/vscode/blob/master/extensions/git/src/commands.ts#L735
[git.push]: https://github.com/Microsoft/vscode/blob/master/extensions/git/src/commands.ts#L670


### git 連携機能の設定項目

settings.json に出てくる Git 関連の設定 (VS Code 1.24-insiders の実装から):

```json
  // 自動フェッチが有効かどうか
  "git.autofetch": false,

  // 自動更新が有効かどうか
  "git.autorefresh": true,

  // レポジトリを自動的に検出するかどうか
  "git.autoRepositoryDetection": true,

  // `Checkout to...` を実行するときに表示されるブランチの種類を制御します。`all` はすべての参照を表示します。`local` はローカル ブランチのみ、`tags`  はタグのみ、`remote` はリモート ブランチのみを表示します。 
  "git.checkoutType": "all",

  // Git リポジトリを同期する前に確認する
  "git.confirmSync": true,

  // Git バッジ カウンターを制御します。`all`  はすべての変更をカウントします。 `tracked` は追跡している変更のみカウントします。 `off` はカウントをオフします。
  "git.countBadge": "all",

  // Git が配色とバッジをエクスプローラーと開いているエディターのビューに提供するかどうかを制御します。
  "git.decorations.enabled": true,

  // Git リポジトリをクローンする既定の場所
  "git.defaultCloneDirectory": null,

  // Git のサブモジュールを自動的に検出するかどうかを制御します。
  "git.detectSubmodules": true,

  // Git サブモジュールの検出の制限を制御します。
  "git.detectSubmodulesLimit": 10,

  // GPG によりデジタル署名されたコミットを有効にします。
  "git.enableCommitSigning": false,

  // Git を有効にするかどうか
  "git.enabled": true,

  // ステージされた変更がない場合はすべての変更をコミットします。
  "git.enableSmartCommit": false,

  // 旧 Git の警告を無視します
  "git.ignoreLegacyWarning": false,

  // リポジトリ内に変更が多い場合は警告を無視します
  "git.ignoreLimitWarning": false,

  // Git が見つからない場合の警告を無視します
  "git.ignoreMissingGitWarning": false,

  // コミット メッセージの入力検証をいつ表示するかを制御します。
  "git.inputValidation": "warn",

  // Git 実行可能ファイルのパス
  "git.path": null,

  // コミット前に Git が保存していないファイルを確認すべきかどうかを制御します。
  "git.promptToSaveFilesBeforeCommit": false,

  // Git 変更の表示内にインラインのファイルを開くアクションを表示するかどうかを制御します。
  "git.showInlineOpenFileAction": true

```

- VS Code の Git 操作を無効にする場合は `false` を設定する。標準コマンドは全て見えなくなる

```json
  // Git が有効になっているかどうか
  "git.enabled": true,
```

- 異なる Git バージョンがインストールされており、明示的に利用するバージョンを指定したい場合には、バイナリへのパスを指定する

```json
  // Git 実行可能ファイルのパス
  "git.path": null,
```

すでに Git リポジトリとして構成されるフォルダを開いている VS Code 上で、異なる Git リポジトリとして構成されているフォルダに配置されるファイルを開くと、そのファイルを含むリポジトリ情報が SCM ビューに追加される仕様になっていた。 

   - See [When I Open Just One File in Initialized Git Folder - Source Control Shows Number of Changed Files · Issue #35555 · Microsoft/vscode](https://github.com/Microsoft/vscode/issues/35555))

![1.20] で、このリポジトリの自動認識機能を抑制することが可能になった。下記設定を `false` にする。
ただし、これを `false` にしてしまうと、単体ファイルとして開くことになるため、VS Code の Git 拡張機能のトラッキング対象として扱われなくなる。ファイルを編集してもエディタ上には何も反映されない。惜しい。

```json 
  // Whether repositories should be automatically detected
  "git.autoRepositoryDetection": true,
```

### 出力パネル

git の機能ではなく、VS code の機能になります。VS Code が呼び出している git コマンドの出力を表示してくれる。

* `Git: Git 出力表示`

Git リポジトリの操作にコマンドが発行される場合は、実行されたコマンドが`出力`パネルにログとして記録されてゆく。

Git リポジトリとして初期化されていないディレクトリでの出力例:

```
    /usr/local/bin/git から Git 2.9.2 を使用しています
    git rev-parse --show-toplevel
    git rev-parse --show-toplevel
    fatal: Not a git repository (or any of the parent directories): .git

    fatal: Not a git repository (or any of the parent directories): .git

    fatal: Not a git repository (or any of the parent directories): .git
```

## Git の基本 

ここからは、Git Book の [Chapter 2. Git の基本](https://git-scm.com/book/ja/v2/Git-の基本-Git-リポジトリの取得) に掲載されている git コマンド操作と VS Code コマンドを対比させながら見ていきたいと思います。 

### Git リポジトリの取得

> **参考:** [Git - Book: Git の基本 - Git リポジトリの取得](https://git-scm.com/book/ja/v2/Git-の基本-Git-リポジトリの取得)

ユーザーは、リポジトリをどのように用意するかが記載されている。
新たに作成したディレクトリや既存のディレクトリをリポジトリとすることもできるし、既に git リポジトリとして構成されているもからコピー(clone)してきても良い。
とにかく、リポジトリを用意しないとはじまらないよということ。


#### 既存のディレクトリでのリポジトリの初期化

> **参考:** [Git - Book: 既存のディレクトリでのリポジトリの初期化](https://git-scm.com/book/ja/v2/Git-の基本-Git-リポジトリの取得#_既存のディレクトリでのリポジトリの初期化)

* `git init` = `Git: リポジトリの初期化`

> ![](https://img.shields.io/badge/vscode-1.16-orange.svg) VS Code 1.16 では、Multi-root をサポートするために動作が変更されている。ソース管理ビューの上段にある、`リポジトリの初期化` はなくなり、コマンドパレットから `Git: リポジトリの初期化` を実行することに。
> その際、初期化するディレクトリを指定するように促される変更が入った。 [SCM: Support multiple repositories by joaomoreno · Pull Request #31325 · Microsoft/vscode](https://github.com/Microsoft/vscode/pull/31325)

ディレクトリ配下を Git で管理するために必要な操作。この操作により Git リポジトリを取得したことになる。新たに作成したディレクトリや既存のディレクトリを Git リポジトリとして管理するために必要な情報が格納される `.git` が作成される。
作成されるだけで、まだ、何も管理対象にはならないことを覚えておくと良い。

フォルダに .git ディレクトリがない場合は、ソース管理ビューには何も表示されない。

* コマンドパレットから `Git: リポジトリの初期化` を実行

![スクリーンショット 2017-08-30 7.30.18.png](https://qiita-image-store.s3.amazonaws.com/0/65800/7f71b53a-1917-4fbc-0c96-0d7218077fd3.png "スクリーンショット 2017-08-30 7.30.18.png")

 ![1.16] からは、Multi Root Workspaces サポートに絡んで、下記のように folder を指定するよう動作が変更になっている

![スクリーンショット 2017-08-30 7.30.54.png](https://qiita-image-store.s3.amazonaws.com/0/65800/3d393ea9-0a50-7c97-3640-55c785b95561.png "スクリーンショット 2017-08-30 7.30.54.png")

![1.15] まで: 

* ソース管理ビューの上段にある、`リポジトリの初期化` コマンドをクリック

の何れかを実行することで、`git init` 同じ結果を得られる。

![スクリーンショット 2017-08-18 8.06.02.png](https://qiita-image-store.s3.amazonaws.com/0/65800/75565d7b-e10e-e286-df8f-7df877a47d4f.png) 

ディレクトリが Git リポジトリとして初期化され認識されると、ソース管理ビューの上段に `✓` マークが追加されるので、これを目安にすると良い。

![スクリーンショット 2017-08-18 8.06.16.png](https://qiita-image-store.s3.amazonaws.com/0/65800/5d9189d6-4401-5957-0089-e78b3ffad34a.png "スクリーンショット 2017-08-18 8.06.16.png")

すでに、Git リポジトリとして構成されている場合は、何れのメニューも表示されない。

`Git: リポジトリの初期化`を実行した際に投入されるコマンドは下記となる (vscode insiders 1.13):

```bash
git init
git rev-parse --show-toplevel
git status -z -u
git symbolic-ref --short HEAD
git rev-parse master
fatal: ambiguous argument 'master': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

git for-each-ref --format %(refname) %(objectname)
git remote --verbose

git status -z -u
git symbolic-ref --short HEAD
git rev-parse master
fatal: ambiguous argument 'master': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

git for-each-ref --format %(refname) %(objectname)
git remote --verbose
```

#### 既存のリポジトリのクローン

> **参考:** [Git - Book: 既存のリポジトリのクローン](https://git-scm.com/book/ja/v2/Git-の基本-Git-リポジトリの取得#_git_cloning)

* `git clone` = `Git: クローン`

既存の Git リポジトリのコピー(クローン)を作成するには、VS Code のコマンドパレットから `Git: クローン` コマンドを実行する。
クローンされたリポジトリの配置先は、(vscode 1.23 から) native dialog が開くようになったので、そこで指定する。
ディレクトリを固定にしたい場合は、`"git.defaultCloneDirectory"` に配置ディレクトリを設定しておく。

また、シェル (macOS) やコマンドプロンプト (Widnows) 上から、下記のように実行すると `Git: Clone` を叩くことができる: 

* Windows: In a Command Prompt, type: `explorer "vscode://vscode.git/clone?url=https%3A%2F%2Fgithub.com%2FMicrosoft%2Fvscode-vsce.git"`.
* macOS: In a shell, type: `open vscode://vscode.git/clone?url=https%3A%2F%2Fgithub.com%2FMicrosoft%2Fvscode-vsce.git`.


### 変更内容のリポジトリへの記録

> **参考:** [Git - Book: 変更内容のリポジトリへの記録](https://git-scm.com/book/ja/v2/Git-の基本-変更内容のリポジトリへの記録)

#### ファイルの状態の確認

* `git status` = `ソースコード管理ビュー`

ファイルの状態を確認する git status に相当するコマンドは VS Code にはなく、`git status -z -u` コマンドを内部で実行し、VS Code のソースコード管理ビューとファイルエクスプローラにファイルの状態を表示する。([状態表示の簡略化](#状態表示の簡略化)を参照)

#### 新しいファイルの追跡と変更したファイルのステージング

> **参考:** [Git - Book: 新しいファイルの追跡](https://git-scm.com/book/ja/v2/Git-の基本-変更内容のリポジトリへの記録#_tracking_files)
> **参考:** [Git - Book: 変更したファイルのステージング](https://git-scm.com/book/ja/v2/Git-の基本-変更内容のリポジトリへの記録#_変更したファイルのステージング)

* `git add` = `変更のステージング`

ファイルを作成すると、そのファイルは `Untracked files:` となり、`変更のステージング` コマンドを実行することにより追跡対象となる。以後、追跡対象となったファイルの編集も同様に、`変更のステージング` でステージに遷移させる。

`git status` の情報は、`ソース管理ビュー`に反映されるので、それを確認しながら状態を把握する。

例: 変更のステージングを extension.ts ファイルに適用した際のログ:

```bash
git for-each-ref --format %(refname) %(objectname)
git remote --verbose
git show :README.md
git show HEAD:README.md
git add -A -- /Users/satokaz/Gits/vscode-bs-ctrlchar-remover/src/extension.ts
git status -z -u
git symbolic-ref --short HEAD
git rev-parse master
git rev-parse --symbolic-full-name --abbrev-ref master@{u}
fatal: no upstream configured for branch 'master'
```

#### 状態表示の簡略化

> **参考:** [Git - Book: 2.2 Git の基本 - 変更内容のリポジトリへの記録: 状態表示の簡略化](https://git-scm.com/book/ja/v2/Git-の基本-変更内容のリポジトリへの記録#_状態表示の簡略化)

* `git status -s` = 

`git status -s` で得られる簡略表示と同じ情報が、ソース管理ビューで提供される。
ソース管理ビューには、`git status -s` の出力が現す 1 文字目(ステージされたファイルの状態)と、2 文字目(ファイルが変更されたかどうか)が`ステージング済みの変更`と`変更`にあるそれぞれのファイル名に反映される。

また、![1.18] から `git status` の情報が、File Explorer に反映されるようになった。(See [Git status in File Explorer](https://code.visualstudio.com/updates/v1_18#_git-status-in-file-explorer))

![alt](https://code.visualstudio.com/assets/updates/1_18/git-decorations.png)

下記の 5 つの情報を反映させることができ、それぞれの色を好みの色に変更することが可能:

```json
"workbench.colorCustomizations": {
    "gitDecoration.conflictingResourceForeground": "#ff0000",
    "gitDecoration.deletedResourceForeground": "#ff0000",
    "gitDecoration.ignoredResourceForeground": "#ff0000",
    "gitDecoration.modifiedResourceForeground": "#ff0000",
    "gitDecoration.untrackedResourceForeground": "#ff0000",
    "gitDecoration.submoduleResourceForeground": "#ff0000"
}
```
|  状態      |                                              |
| --------- | --------------------------------------------- | 
| modified  | "gitDecoration.modifiedResourceForeground"    |
| deleted   | "gitDecoration.deletedResourceForeground"     |
| untracked | "gitDecoration.untrackedResourceForeground"   |
| ignored   | "gitDecoration.ignoredResourceForeground"     |
| conflict  | "gitDecoration.conflictingResourceForeground" |
| submodule | "gitDecoration.submoduleResourceForeground"   |

`"git.decorations.enabled": false` (default: true) で無効にすることも可能。

#### ファイルの無視

> **参考:** [Git - Book: 2.2 Git の基本 - 変更内容のリポジトリへの記録: ファイルの無視](https://git-scm.com/book/ja/v2/Git-の基本-変更内容のリポジトリへの記録#_ignoring)

* .gitignore を扱うコマンド = `Git: ファイルを .gitignore に追加`

.gitignore を扱うための `Git: ファイルを .gitignore に追加` コマンドが、1.14 から追加された。
既存の .gitignore ファイルを編集するためのコマンドとなり、ファイルが存在しない場合は何もしないコマンド。

そのため、.gitignore は、ユーザー側で用意する必要がある。VS Code から扱うなら、下記の拡張機能をインストールしておくのもオススメ。


| 拡張機能                        | 概要                  | 
| ------------------------------ | ---------------------|
| [gi][gi]                       | 言語や開発環境にあわせた .gitignore ファイルのテンプレートを生成してくれる [gitignore.io](gitignore.io) を VS Code から利用するための拡張機能。.gitignore ファイルが生成され、複数のテンプレートを追記してゆくことも可能。|
| [ignore "g" it][ignore "g" it] | VS Code のエクスプローラー上で選択したフォルダやファイルの拡張子をコンテキストメニューから .gitignore に追加/削除可能できる拡張機能(コマンドパレットからも可能) |
|[.gitignore Generator] | gitignore.io  |


[gi]: https://marketplace.visualstudio.com/items?itemName=rubbersheep.gi
[ignore "g" it]: https://marketplace.visualstudio.com/items?itemName=Andreabbondanza.ignoregit
[.gitignore Generator]: https://marketplace.visualstudio.com/items?itemName=piotrpalarz.vscode-gitignore-generator

#### ステージされている変更/されていない変更の閲覧

> **参考:** [Git - Book: 2.2 Git の基本 - 変更内容のリポジトリへの記録 - ステージされている変更/されていない変更の閲覧](https://git-scm.com/book/ja/v2/Git-の基本-変更内容のリポジトリへの記録#_git_diff_staged)

[Version Control in VS Code - Viewing Diffs](https://code.visualstudio.com/docs/editor/versioncontrol#_viewing-diffs)

* `git diff` = `Git: 変更を開く`

「変更したけれどもまだステージしていない内容」は、
ソース管理ビューで、ファイルをクリックすることで変更点を参照することが可能。または、`Git: 変更を開く` コマンドを実行でも可能。

デフォルトでは、変更前と変更後のファイルを横並びにして差分を表示するが、右上の … メニューにある `Toggle Inline View` でインライン表示することも可能。

「次のコミットに含めるべくステージされた内容」(`git diff --staged or --cached`) のように差分だけを表示する機能はない。 

#### 変更のコミット

> **参考:** [Git - Book: 2.2 Git の基本 - 変更内容のリポジトリへの記録 - 変更のコミット](https://git-scm.com/book/ja/v2/Git-の基本-変更内容のリポジトリへの記録#_committing_changes)

コミットの対象となるのはステージされたものだけ、つまり追加したり変更したりしただけで、まだ git add を実行していないファイルはコミットされないことを覚えておきましょう。とあるので、覚えておく。

* `git commit` = `Git: Commit`

ステージングされたファイルをコミットする:

* `Git: Commit`
* `Git: ステージング済みをコミット`
* `Git: すべてコミット (サインオフ)`
* `Git: コミットしてステージング (サインオフ)`

ステージングされていないファイルも含め全てをコミットする:

* `Git: すべてコミット`

また、コミットメッセージの入力が必須になる。
git コマンドでは、デフォルトのコミットメッセージとして、直近の git status コマンドの結果を入れられるが、VS Code の場合は、それを手軽に入力する方法がない。

Git Hooks の  [githooks - prepare-commit-msg](https://git-scm.com/docs/githooks#_prepare_commit_msg) を利用することで、コミットメッセージをカスタマイズすることもできるみたい。
これと、Git commit message templates を組み合わせれば、cmd+Enter だけで commit 出来るかな？

#### コミットメッセージについて
##### commit message のテンプレート

commit 時に入力するメッセージの雛形をテンプレートからひっぱってくる git commit template も利用可能
`git config --get commit.template` に設定されたファイルからテンプレート情報を引っ張ってきて利用している。

-   [Git commit message templates #7830](https://github.com/Microsoft/vscode/issues/7830)
-   [Better Commit Messages with a .gitmessage Template](https://robots.thoughtbot.com/better-commit-messages-with-a-gitmessage-template)

#### ステージングエリアの省略

* `git add -a` = `Git: すべてコミット`

追跡対象となっているファイルを自動的にステージしてからコミットを行います。

#### ファイルの削除

> **参考:** [Git - Book: 2.2 Git の基本 - 変更内容のリポジトリへの記録 - ファイルの削除](https://git-scm.com/book/ja/v2/Git-の基本-コミット履歴の閲覧#_removing_files)

* `git rm`

VS Code のコマンドは提供されておらず、エクスプローラからファイルを削除することで、`deleted:` となるので、後は、ステージングに遷移させてからコミットでも良いし、`Git: すべてコミット` で一気にやってしまっても良い。

#### ファイルの移動

> **参考:** [Git - Book: 2.2 Git の基本 - 変更内容のリポジトリへの記録 - ファイルの移動](https://git-scm.com/book/ja/v2/Git-の基本-コミット履歴の閲覧#_git_mv)

* `git mv`

こちらも、特別な VS Code のコマンドは提供されておらず、ファイルの削除と同じになるのかな。

### コミット履歴の閲覧

> **参考:** [Git - Book: 2.3 Git の基本 - コミット履歴の閲覧](https://git-scm.com/book/ja/v2/Git-の基本-コミット履歴の閲覧#_viewing_history)

コミットログを見るための git log 相当のコマンドは現時点では提供されていないため、下記の拡張機能で補完する。

| 拡張機能                           | 概要                                           |
|---------------------------------- | --------------------------------------------- |
|[Git History (git log)][GitHistory] | git log をグラフィカルに参照することが可能           |
|[Git Lens][Git Lens]                | VS Code の Git 機能と連携し様々な機能を付加してくれる |
|[Git History Diff][githd]           | git log を参照するための拡張機能                   |

[GitHistory]: https://marketplace.visualstudio.com/items?itemName=donjayamanne.githistory
[Git Lens]: https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens
[githd]: https://marketplace.visualstudio.com/items?itemName=huizhou.githd


### 作業のやり直し

> **参考:** [Git - Book: 2.4 Git の基本 - 作業のやり直し](https://git-scm.com/book/ja/v2/Git-の基本-作業のやり直し)

* `git commit --amend`

#### ステージしたファイルの取り消し:

> **参考:** [Git - Book: 2.4 Git の基本 - 作業のやり直し - ステージしたファイルの取り消し](https://git-scm.com/book/ja/v2/Git-の基本-作業のやり直し#_unstaging)

* `Git: 変更のステージング解除`
* `Git: すべての変更のステージング解除`
* `Git: 選択した範囲をアンステージする`

#### ファイルへの変更の取り消し

> **参考:** [Git - Book: 2.4 Git の基本 - 作業のやり直し - ファイルへの変更の取り消し](https://git-scm.com/book/ja/v2/Git-の基本-作業のやり直し)

`Git: 変更を破棄`
`Git: すべての変更を破棄`

#### コミットの取り消し

> **参考:** [Git - Book: 7.7 Git のさまざまなツール - リセットコマンド詳説](https://git-scm.com/book/ja/v2/Git-のさまざまなツール-リセットコマンド詳説)

戻す:

- `Git: 前回のコミットを元に戻す`

#### VS Code の "すべての変更を破棄" について

* [Semantics of &quot;Discard All Changes&quot; in Source Control panel considered harmful · Issue #32459 · Microsoft/vscode](https://github.com/Microsoft/vscode/issues/32459)

### リモートでの作業

> **参考:** [Git - Book: 2.5 Git の基本 - リモートでの作業](https://git-scm.com/book/ja/v2/Git-の基本-リモートでの作業)

Git を使ったプロジェクトで共同作業を進めていくには、リモートリポジトリの扱い方を知る必要があります。リモートリポジトリとは、インターネット上あるいはその他ネットワーク上のどこかに存在するプロジェクトのことです。

#### リモートの表示

> **参考:** [Git - Book: 2.5 Git の基本 - リモートでの作業 - リモートの表示](https://git-scm.com/book/ja/v2/Git-の基本-リモートでの作業)

* `git remote -v`

#### リモートリポジトリの追加

> **参考:** [Git - Book: 2.5 Git の基本 - リモートでの作業 - リモートリポジトリの追加](https://git-scm.com/book/ja/v2/Git-の基本-リモートでの作業)

* `git remote add`

#### リモートからのフェッチ、そしてプル

> **参考:** [Git - Book: 2.5 Git の基本 - リモートでの作業 - リモートからのフェッチ、そしてプル](https://git-scm.com/book/ja/v2/Git-の基本-リモートでの作業#_fetching_and_pulling)

* `git fetch` = `Git: 最新の情報に更新`
* `git pull` = `Git: プル`
* `git pull branch` = `Git: 指定元からプル`

以前の VS Code では、定期的に `git fetch` を実行し remote repository から更新情報を取得する動作がデフォルトだったが、git 認証用のポップアップが表示されることが混乱を招き、多くのユーザーが自動 fetch を無効にしていたため、![1.19] からデフォルトを無効とした。

動作が気に入らない場合は、`"git.autofetch": false` を `true` に変更する。

> 無効なった経緯は、[Set git.autofetch to disabled, by default · Issue #34684 · Microsoft/vscode](https://github.com/Microsoft/vscode/issues/34684)で。

* fetch は、持ってくるだけで、merge されたり作業中の内容を書き換えたりしない。自分で merge する必要がある
* pull は、最初に clone した remote repository からデータを取得し、現在作業中のコードへの merge を試みる

また、pull する際に rebase を適用することも可能

* `git pull -r` = `Git: プル(リベース)`

pull の際に、merge ではなく、rebase を適用する。

#### リモートへのプッシュ

> **参考:** [Git - Book: 2.5 Git の基本 - リモートでの作業 - リモートへのプッシュ](https://git-scm.com/book/ja/v2/Git-の基本-リモートでの作業#_pushing_remotes)

* `git push` = `Git: プッシュ` 
* リモートを選択して psuh する場合は、`Git: プッシュ先`

ステータスバーの同期アイコンは `git.sync` コマンドを実行している。

![2017-07-16-17-09-45.png](https://qiita-image-store.s3.amazonaws.com/0/65800/a5dc9dde-b06c-046d-ee8c-bb2a0e17f356.png)

#### リモートの調査

> **参考:** [Git - Book: 2.5 Git の基本 - リモートでの作業 - リモートの調査](https://git-scm.com/book/ja/v2/Git-の基本-リモートでの作業#_inspecting_remote)

* `git remote show`

#### リモートの削除・リネーム

> **参考:** [Git - Book: 2.5 Git の基本 - リモートでの作業 - リモートの削除・リネーム](https://git-scm.com/book/ja/v2/Git-の基本-リモートでの作業#_リモートの削除_リネーム)

* `git remote rename`



### Git の基本 - タグ

> **参考:** [Git - Book: 2.6 Git の基本 - タグ](https://git-scm.com/book/ja/v2/Git-の基本-タグ)

 ![1.16]
 
重要なポイントに印をつけることができる tag 機能は、VS Code 1.16 で実装された。

* `Git: タグを作成` (Create Tag)
* `Git: タグをつけてプッシュ` (Push With Tags)

[[#25575] Add Git Tag feature. by ashutoshdhundhara · Pull Request #26999 · Microsoft/vscode](https://github.com/Microsoft/vscode/pull/26999) が merge されたが、`showTags` の機能は削除されている。

VS Code で、Tag 一覧を参照したい場合は、拡張機能: Git Tags を利用する

[Git&#32;Tags&#32;-&#32;Visual&#32;Studio&#32;Marketplace](https://marketplace.visualstudio.com/items?itemName=howardzuo.vscode-git-tags)


## Git のブランチ機能 (Chapter 3)

> **参考:** [Git - Book: Chapter 3. Git のブランチ機能](https://git-scm.com/book/ja/v2/Git-のブランチ機能-ブランチとは)

ブランチとは、開発の本流から分岐し、本流の開発を邪魔することなく作業を続ける機能のことで、Git では頻繁にブランチ作成とマージを繰り返すワークフローを推奨している。

Git Book のこの章で、Git のブランチの仕組みについて把握しておくと良い。

### ブランチとは

> **参考:** [Git - Book: 3.1 Git のブランチ機能 - ブランチとは](https://git-scm.com/book/ja/v2/Git-のブランチ機能-ブランチとは)

Git Book で、ブランチや HEAD などの考え方を把握しておくと良い。

### 新しいブランチの作成

> **参考:** [Git - Book: 3.1 Git のブランチ機能 - ブランチとは - 新しいブランチの作成](https://git-scm.com/book/ja/v2/Git-のブランチ機能-ブランチとは#_create_new_branch)

* `git branch` = `Git: 分岐の作成...`

VS Code 1.11 から、branch を作成するには、コマンドパレットから `Git: 分岐の作成...` を実行する必要がある。

### ブランチの切り替え

* `git checkout` = `Git: チェックアウト先...`

> **参考:** [Git - Book: 3.1 Git のブランチ機能 - ブランチとは - ブランチの切り替え](https://git-scm.com/book/ja/v2/Git-のブランチ機能-ブランチとは#_switching_branches)

ステータスバーの左下に現在、アクティブになっているブランチが表示されている。それをクリックすることで、そのリポジトリが持っているブランチの一覧が表示され、そこから任意のブランチを選択することで切り替えることができる。

また、VS Code 1.15 (8 月にリリース予定)からは、ステータスバーと `Git: チェックアウト先...` コマンドに `+ Create new branch` が追加され、これを選択することで、新しいブランチを作成することもできるようになっている。

* [Can no longer create branch when running `Git: Checkout` #21439](https://github.com/Microsoft/vscode/issues/21439)

### Git のブランチ機能 - ブランチとマージの基本

> **参考:** [Git - Book: 3.2 Git のブランチ機能 - ブランチとマージの基本](https://git-scm.com/book/ja/v2/Git-のブランチ機能-ブランチとマージの基本)

ブランチを作成し、その上で更新作業を行い、必要に応じて master や他のブランチとマージを繰り返すフローになる。

#### ブランチの基本

> **参考:** [Git - Book: 3.2 Git のブランチ機能 - ブランチとマージの基本 - ブランチの基本](https://git-scm.com/book/ja/v2/Git-のブランチ機能-ブランチとマージの基本#_basic_branching)

マージを行うために必要なブランチの基本を把握する。

#### マージの基本

> **参考:** [Git - Book: 3.2 Git のブランチ機能 - ブランチとマージの基本 - マージの基本](https://git-scm.com/book/ja/v2/Git-のブランチ機能-ブランチとマージの基本#_basic_merging)

* `Git: ブランチをマージ...`

切り出したブランチで作業した内容を master ブランチにマージする基本を把握する。

#### マージ時のコンフリクト

> **参考:** [Git - Book: 3.2 Git のブランチ機能 - ブランチとマージの基本 - マージ時のコンフリクト](https://git-scm.com/book/ja/v2/Git-のブランチ機能-ブランチとマージの基本#_basic_merge_conflict)

vscode 1.13 から、Marketplace で配布されていた [Better Merge](https://marketplace.visualstudio.com/items?itemName=pprice.better-merge) 拡張機能が core extension として統合されている。

- [Microsoft/vscode](https://github.com/Microsoft/vscode/tree/master/extensions/merge-conflict)

マージのコンフリクトが発生しても、簡単に解決できるようになっている。

### Git のブランチ機能 - ブランチの管理

> **参考:** [Git - Book: 3.3 Git のブランチ機能 - ブランチの管理](https://git-scm.com/book/ja/v2/Git-のブランチ機能-ブランチの管理)

ブランチの作成、マージ、そして削除を理解した上で、いくつかのコマンドベースのブランチ管理ツールについて把握しておく。

#### Git のブランチ機能 - ブランチでの作業の流れ

> **参考:** [Git - Book: 3.4 Git のブランチ機能 - ブランチでの作業の流れ](https://git-scm.com/book/ja/v2/Git-のブランチ機能-ブランチでの作業の流れ)

ブランチとマージの基本操作を理解した上で、それを実際にどう使えば良いかを解説するセクション。気軽にブランチを切れることでどういった作業ができるようになるのかを説明しているので、確認しておくと良いです。

#### Git のブランチ機能 - リモートブランチ

> **参考:** [Git - Book: 3.5 Git のブランチ機能 - リモートブランチ](https://git-scm.com/book/ja/v2/Git-のブランチ機能-リモートブランチ)

* `git ls-remote [remote]`
* `git remote show [remote]`

VS Code では、これらを実現する単一のコマンドは提供されていない。

#### プッシュ(リモートブランチへのプッシュ)

> **参考:** [Git - Book: 3.5 Git のブランチ機能 - リモートブランチ - プッシュ](https://git-scm.com/book/ja/v2/Git-のブランチ機能-リモートブランチ#_pushing_branches)

* `git push` = `Git: プッシュ`

ローカルブランチの内容が自動的にリモートと同期されることはなく、共有したいブランチは、明示的にプッシュする必要がある。

#### 追跡ブランチ

> **参考:** [Git - Book: 3.5 Git のブランチ機能 - リモートブランチ - 追跡ブランチ](https://git-scm.com/book/ja/v2/Git-のブランチ機能-リモートブランチ#_tracking_branches)

#### プル

> **参考:** [Git - Book: 3.5 Git のブランチ機能 - リモートブランチ - プル](https://git-scm.com/book/ja/v2/Git-のブランチ機能-リモートブランチ#_プル)

* `git pull` = `Git: プル`

#### リモートブランチの削除

> **参考:** [Git - 3.5 Git のブランチ機能 - リモートブランチ - Book: リモートブランチの削除](https://git-scm.com/book/ja/v2/Git-のブランチ機能-リモートブランチ#_delete_branches)

* `git push --delete` = `Git: ブランチの削除...`


### リベース

> **参考:** [Git - Book: 3.6 Git のブランチ機能 - リベース](https://git-scm.com/book/ja/v2/Git-のブランチ機能-リベース)

リベースについて「どういう意味か」「どのように行うのか」「なぜそんなにもすばらしいのか」「どんなときに使うのか」が説明されている。
VS Code で直接リベースを叩くコマンドは提供されていない(はず)。

## Git のさまざまなツール (Chapter 7)

> **参考:** [Git - Book: 7. Git のさまざまなツール](https://git-scm.com/book/ja/v2/Git-のさまざまなツール-リビジョンの選択)

Git - Book Chapter 7 で紹介されるいくつかのツールも VS Code へ実装されています。

### 行単位のステージングと取り消し

> **参考:** [Git - Book: 7.2 Git のさまざまなツール - 対話的なステージング](https://git-scm.com/book/ja/v2/Git-のさまざまなツール-対話的なステージング#_パッチのステージ)

Git では、ファイルの特定の箇所だけをステージして他の部分はそのままにしておくということもできますが、これを VS Code から行うことが可能です。

コマンドパレットから、直接、

-   `Git: 選択した範囲をステージする` (`git add -p`)
-   `Git: 選択した範囲をアンステージする` (`git reset -p`)

を実行するか、または、

diff 画面の右上 `…` をクリックするとでてくるメニューから選択することで、差分を確認しながら適用することが可能。選択は、1 行だけが対象なら行を選択する必要はなく、カーソルをその行に置くだけでも選択と見なされる。

![スクリーンショット 2017-04-19 7.42.34.png](https://qiita-image-store.s3.amazonaws.com/0/65800/6012c373-2ab7-0e03-722b-f61fe07f770c.png "スクリーンショット 2017-04-19 7.42.34.png")

関連 Issues:

- [Export more git commands · Issue #18185 · Microsoft/vscode](https://github.com/Microsoft/vscode/issues/18185)
- [Add line per line in Git panel · Issue #18509 · Microsoft/vscode](https://github.com/Microsoft/vscode/issues/18509)
- [Improve git partial staging discoverability · Issue #3563 · Microsoft/vscode](https://github.com/Microsoft/vscode/issues/3563)
- [git reset -p : Reset line per line (and maybe per block too) · Issue #19118 · Microsoft/vscode](https://github.com/Microsoft/vscode/issues/19118)


### 作業の隠しかたと消しかた 

> **参考:** [Git - Book: 7.3 Git のさまざまなツール - 作業の隠しかたと消しかた](https://git-scm.com/book/ja/v2/Git-のさまざまなツール-作業の隠しかたと消しかた)

現在作業している内容をすぐにコミットしたくはないけど、ちょっとブランチを切り替えて作業したいときなどに利用する。stash でコミットされていない変更内容を一時的に待避させ、作業が終わったら、pop で待避していたものを戻すことができる。

#### 自分の作業を隠す (git stash)

 ![1.16]

> **参考:** [Git - Book: 7.3 Git のさまざまなツール - 作業の隠しかたと消しかた - 自分の作業を隠す](https://git-scm.com/book/ja/v2/Git-のさまざまなツール-作業の隠しかたと消しかた#_自分の作業を隠す)

コマンドラインからの `git stash` は、引数なしで実行でき、hash と直近のコミットメッセージを利用して stash message を自動生成してくれる。
VS Code の `Git: Stash` コマンドでは、stash message の入力を求められるが、何も入力せずに `Enter` を押すことで同様の動作となる。

stash を作成し待避させる: 

* `git stash` = `Git: スタッシュ`
* `git stash -u ` = `Git: スタッシュ(未追跡ファイルを含む)`

stash を選択して戻す:

* `git stash pop` = `Git: スタッシュを適用して削除...`

直近の stash を戻す:

* ``Git: 最新のスタッシュを適用して削除`

また、Git Lens 拡張機能で Stash 管理を VS Code に統合できる。

| 拡張機能               | 概要            | 
| -------------------- | --------------- |
| [Git Lens][Git Lens] | stash の管理を VS Code 上で行える、Git Stashes explorer を提供してくれる。VS Code 1.16 の `Git: Stash` 関連コマンドと連携可能 | [Git Lens]: https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens|


### 歴史の書き換え

> **参考:** [Git - Book: 7.6 Git のさまざまなツール - 歴史の書き換え](https://git-scm.com/book/ja/v2/Git-のさまざまなツール-歴史の書き換え)

Git のすばらしい点のひとつは、何をどうするかの決断をぎりぎりまで先送りできることです。 

* どのファイルをどのコミットに含めるのかは、ステージングエリアの内容をコミットする直前まで変更することができる
* 既に作業した内容でも stash コマンドを使えばまだ作業していないことにできる
* すでにコミットしてしまった変更についても、それを書き換えてまるで別の方法で行ったかのようにすることもできる
* コミットの順序を変更したり、
* コミットメッセージやコミットされるファイルを変更したり、
* 複数のコミットをひとつにまとめたり
* ひとつのコミットを複数に分割したり
* コミットそのものをなかったことにしたり

と、コミットの歴史を思い通りに書き換えてから他の人と共有できるようにする様々な手段。

#### 直近のコミットの変更

> **参考:** [Git - Book: 直近のコミットの変更](https://git-scm.com/book/ja/v2/Git-のさまざまなツール-歴史の書き換#_git_amend)

* git commit -amend

変更後のメッセージを含む新しいコミットを作成して直近のコミットをそれで置き換える。
この処理を行うと commit の SHA-1 が変わる事に注意。非常に小規模な rebase のようなもので、すでに push しているかどうかを判断基準にし、もし push した後なら commit は書き換えないようにしましょう。とのこと。

### サブモジュール

> **参考:** [Git - Book: 7.6 Git のさまざまなツール - サブモジュール](https://git-scm.com/book/ja/v2/Git-のさまざまなツール-サブモジュール)

「ふたつのプロジェクトはそれぞれ別のものとして管理したい。だけど、一方を他方の一部としても使いたい」という問題を解決するための機能。

[サブモジュール使用時に気をつけるべきこと](https://git-scm.com/book/ja/v2/Git-のさまざまなツール-サブモジュール#_サブモジュール使用時に気をつけるべきこと)についても言及されているので確認をしておく。 

![1.20] で追加される機能となり、`S` としてマークされる。 

* [Visual Studio Code の git submodule 対応を試してみる - Qiita](https://qiita.com/diescake/items/814c1cadf3302d2273c5)

submodule の数だけ git プロセスが起動してしまうようで、数百の submodule があるようなリポジトリを開くと応答がなくなってしまうそう。そのため、VS Code 1.22 では、`git.detectSubmodulesLimit` 設定により submodule の数に制限をかけている (default: 10): 

* [VSCode spawns hundreds of Git processes when opening a project with lots of submodules #43528](https://github.com/Microsoft/vscode/issues/43528)

#### サブモジュールの作り方

> **参考:** [Git - Book: 7.6 Git のさまざまなツール - サブモジュールの作り方](https://git-scm.com/book/ja/v2/Git-のさまざまなツール-サブモジュール#_starting_submodules)

#### サブモジュールを含むプロジェクトのクローン

> **参考:** [Git - Book: 7.6 Git のさまざまなツール - サブモジュールを含むプロジェクトのクローン](https://git-scm.com/book/ja/v2/Git-のさまざまなツール-サブモジュール#_cloning_submodules)

#### サブモジュールを含むプロジェクトでの作業

> **参考:** [Git - Book: 7.6 Git のさまざまなツール - サブモジュールを含むプロジェクトでの作業](https://git-scm.com/book/ja/v2/Git-のさまざまなツール-サブモジュール#_サブモジュールを含むプロジェクトでの作業)

#### サブモジュールに加えた変更の公開

> **参考:** [Git - Book: 7.6 Git のさまざまなツール - サブモジュールに加えた変更の公開](https://git-scm.com/book/ja/v2/Git-のさまざまなツール-サブモジュール#_publishing_submodules)

### 変更されたサブモジュールのマージ

> **参考:** [Git - Book: 7.6 Git のさまざまなツール - 変更されたサブモジュールのマージ](https://git-scm.com/book/ja/v2/Git-のさまざまなツール-サブモジュール#_publishing_submodules)

#### 変更されたサブモジュールのマージ

> **参考:** [Git - Book: 7.6 Git のさまざまなツール - サブモジュールの作り方](https://git-scm.com/book/ja/v2/Git-のさまざまなツール-サブモジュール#_変更されたサブモジュールのマージ)

## 綺麗にまとめられないので、ひとまず下記においとく

### Added support for encodings for Git.

- [PR #24911 Added support for encodings for Git.](https://github.com/Microsoft/vscode/pull/24911)

utf-8 固定だったものを `files.encoding` をベースにするよう変更

## 外部エディタ/Diff ツール（差分表示ツール）としての Visual Studio Code

長くなったので、別コンテンツとして切り出しました:

* [外部エディタ/Diff ツール（差分表示ツール）としての Visual Studio Code (git と SourceTree で使ってみる) - Qiita](http://qiita.com/satokaz/items/55a3b076979e3f9d0e9b)

## あると便利な拡張機能

* [Visual Studio Code Extensions Roundup - Git August 2016](https://code.visualstudio.com/blogs/2016/07/29/extensions-roundup-git)

### Open in SourceTree

開いているプロジェクトを [SourceTree](https://www.sourcetreeapp.com) クライアントで開く拡張機能

* [Open&#32;in&#32;SourceTree&#32;-&#32;Visual&#32;Studio&#32;Marketplace](https://marketplace.visualstudio.com/items?itemName=morrislaptop.vscode-open-in-sourcetree)

<img width="960" alt="スクリーンショット 2018-01-07 14.20.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/65800/b8b8b178-6235-6c69-6a1f-9d45c10b4a0f.png">

### Open in Fork 

開いているプロジェクトを [Fork](https://git-fork.com) クライアントで開く拡張機能

 * [Open&#32;in&#32;Fork&#32;-&#32;Visual&#32;Studio&#32;Marketplace](https://marketplace.visualstudio.com/items?itemName=spacek33z.vscode-open-in-gitfork)

![スクリーンショット 2017-08-18 9.14.35.png](https://qiita-image-store.s3.amazonaws.com/0/65800/6f107749-f953-8d83-0606-178a62113624.png "スクリーンショット 2017-08-18 9.14.35.png")

### Open in GitHub

* [Open&#32;in&#32;GitHub&#32;-&#32;Visual&#32;Studio&#32;Marketplace](https://marketplace.visualstudio.com/items?itemName=fabiospampinato.vscode-open-in-github)

## プライベートな Git リポジトリ

プライベートな Git リモートリポジトリが欲しい場合は、無償利用可能な [Visual Studio Team Services](https://www.visualstudio.com/products/visual-studio-team-services-vs) (または VTST と略して呼ばれる。旧 Visual Studio Online) も選択肢に入れられる。
無償で制限なくプライベート Git リポジトリを利用することが可能だし、Visual Studio で利用される [TFVC(Team Foundation Version Control)](https://www.visualstudio.com/ja/team-services/tfvc/)リポジトリも使える。
TFVC を利用したい場合は、[Visual Studio Team Services 拡張機能](https://marketplace.visualstudio.com/items?itemName=ms-vsts.team)が必要。

* [Official Release of TFVC Support for Visual Studio Code](https://blogs.msdn.microsoft.com/visualstudioalm/2017/04/12/official-release-of-tfvc-support-for-visual-studio-code/)

外部リポジトリ(GitHub など)を source repository として VSTS と連携できる。GitHub 側に commit すると、VSTS 側で build task を実行することなども可能みたい。

* [Getting Started with Git in Team Services](https://www.visualstudio.com/en-us/get-started/code/gitquickstart)
* [Visual Studio Online Supports True Cross-Platform Development](https://blogs.msdn.microsoft.com/visualstudioalm/2015/06/05/visual-studio-online-supports-true-cross-platform-development/)
* [Visual Studio OnlineとGitHubを連携する方法 Visual Studio Online側準備編 #tfsug](http://changesworlds.com/2015/07/how-to-cooperation-of-visual-studio-online-and-github-visual-studio-online-side-setup-guide/)

外部のサービスを kick できる Services Hook もあるので、たとえば commit されたら Slack へ通知とか、jenkins に Job 投入とかできる。

## Thanks

* [@sahara](https://qiita.com/sahara)
* [@f440](https://qiita.com/f440)