Git-quick-guide

提供:Dev Guides
移動先:案内検索

Git-基本概念

バージョン管理システム

  • バージョン管理システム(VCS)*は、ソフトウェア開発者が協力して作業の完全な履歴を維持できるようにするソフトウェアです。

以下は、VCSの機能です-

  • 開発者が同時に作業できるようにします。
  • 互いの変更を上書きすることはできません。
  • すべてのバージョンの履歴を保持します。

VCSの種類は次のとおりです-

  • 集中型バージョン管理システム(CVCS)。
  • 分散/分散バージョン管理システム(DVCS)。

この章では、分散バージョン管理システム、特にGitのみに集中します。 Gitは分散バージョン管理システムに分類されます。

分散バージョン管理システム

集中型バージョン管理システム(CVCS)は、中央サーバーを使用してすべてのファイルを保存し、チームの共同作業を可能にします。 しかし、CVCSの主な欠点は、その単一障害点、つまり中央サーバーの障害です。 残念ながら、中央サーバーが1時間ダウンすると、その時間中は誰もコラボレーションできなくなります。 最悪の場合でも、中央サーバーのディスクが破損し、適切なバックアップが取られていないと、プロジェクトの全履歴が失われます。 ここでは、分散バージョン管理システム(DVCS)が登場します。

DVCSクライアントは、ディレクトリの最新のスナップショットをチェックアウトするだけでなく、リポジトリを完全にミラーリングします。 サーバーがダウンした場合、任意のクライアントのリポジトリをサーバーにコピーして復元することができます。 すべてのチェックアウトは、リポジトリの完全バックアップです。 Gitは中央サーバーに依存しないため、オフラインのときに多くの操作を実行できます。 オフライン時に変更をコミットし、ブランチを作成し、ログを表示し、他の操作を実行できます。 ネットワーク接続が必要なのは、変更を公開して最新の変更を行う場合のみです。

Gitの利点

無料でオープンソース

GitはGPLのオープンソースライセンスの下でリリースされます。 インターネット経由で自由に利用できます。 Gitを使用すると、1円も支払うことなく、プロパティプロジェクトを管理できます。 オープンソースであるため、ソースコードをダウンロードし、要件に応じて変更を行うこともできます。

速くて小さい

ほとんどの操作はローカルで実行されるため、速度の面で大きな利点があります。 Gitは中央サーバーに依存しません。そのため、操作ごとにリモートサーバーと対話する必要はありません。 Gitのコア部分はCで記述されているため、他の高レベル言語に関連する実行時のオーバーヘッドが回避されます。 Gitはリポジトリ全体をミラーリングしますが、クライアント側のデータのサイズは小さくなります。 これは、クライアント側でデータを圧縮および保存する際のGitの効率を示しています。

暗黙的なバックアップ

データのコピーが複数ある場合、データを失う可能性は非常にまれです。 クライアント側に存在するデータはリポジトリをミラーリングするため、クラッシュまたはディスクの破損が発生した場合に使用できます。

セキュリティ

Gitは、セキュアハッシュ関数(SHA1)と呼ばれる一般的な暗号化ハッシュ関数を使用して、データベース内のオブジェクトに名前を付けて識別します。 すべてのファイルとコミットはチェックサムされ、チェックアウト時にチェックサムによって取得されます。 これは、Gitを知らない限り、Gitデータベースからファイル、日付、コミットメッセージおよびその他のデータを変更することは不可能であることを意味します。

強力なハードウェアは不要

CVCSの場合、中央サーバーはチーム全体のリクエストに応えるのに十分強力である必要があります。 小さなチームの場合、これは問題ではありませんが、チームの規模が大きくなると、サーバーのハードウェア制限がパフォーマンスのボトルネックになる可能性があります。 DVCSの場合、開発者は変更をプッシュまたはプルする必要がない限り、サーバーと対話しません。 面倒な作業はすべてクライアント側で行われるため、サーバーのハードウェアは非常にシンプルにできます。

より簡単な分岐

CVCSは安価なコピーメカニズムを使用します。新しいブランチを作成すると、すべてのコードが新しいブランチにコピーされるため、時間がかかり、効率的ではありません。 また、CVCSでのブランチの削除とマージは複雑で時間がかかります。 ただし、Gitによるブランチ管理は非常に簡単です。 ブランチの作成、削除、マージには数秒しかかかりません。

DVCSの用語

ローカルリポジトリ

すべてのVCSツールは、作業用コピーとしてプライベートな職場を提供します。 開発者はプライベートな職場で変更を行い、コミット後、これらの変更はリポジトリの一部になります。 Gitは、リポジトリ全体のプライベートコピーを提供することで、さらに一歩前進します。 ユーザーは、このリポジトリを使用して、ファイルの追加、ファイルの削除、ファイルの名前変更、ファイルの移動、変更のコミットなど、多くの操作を実行できます。

作業ディレクトリとステージング領域またはインデックス

作業ディレクトリは、ファイルがチェックアウトされる場所です。 他のCVCSでは、開発者は通常、変更を行い、変更をリポジトリに直接コミットします。 しかし、Gitは別の戦略を使用します。 Gitは、変更されたすべてのファイルを追跡しません。 操作をコミットするたびに、Gitはステージング領域にあるファイルを探します。 ステージング領域に存在するファイルのみが、すべての変更されたファイルではなく、コミットの対象と見なされます。

Gitの基本的なワークフローを見てみましょう。

  • ステップ1 *-作業ディレクトリからファイルを変更します。
  • ステップ2 *-これらのファイルをステージング領域に追加します。
  • ステップ3 *-ステージング領域からファイルを移動するコミット操作を実行します。 プッシュ操作後、変更はGitリポジトリに永続的に保存されます。

Gitチュートリアル

「sort.c」と「search.c」という2つのファイルを変更し、各操作に2つの異なるコミットが必要だとします。 ステージング領域に1つのファイルを追加して、コミットを実行できます。 最初のコミットの後、別のファイルに対して同じ手順を繰り返します。

# First commit
[bash]$ git add sort.c

# adds file to the staging area
[bash]$ git commit –m “Added sort operation”

# Second commit
[bash]$ git add search.c

# adds file to the staging area
[bash]$ git commit –m “Added search operation”

Blobは* B inary L arge Ob * jectを表します。 ファイルの各バージョンはblobで表されます。 Blobはファイルデータを保持しますが、ファイルに関するメタデータは含みません。 これはバイナリファイルであり、Gitデータベースでは、そのファイルのSHA1ハッシュと呼ばれます。 Gitでは、ファイルは名前でアドレス指定されません。 すべてがコンテンツに対応しています。

ツリーは、ディレクトリを表すオブジェクトです。 それは他のサブディレクトリと同様にブロブを保持します。 ツリーは、ツリーオブジェクトの SHA1 ハッシュとも呼ばれるBLOBとツリーへの参照を格納するバイナリファイルです。

コミット

コミットは、リポジトリの現在の状態を保持します。 コミットは SHA1 ハッシュによっても名前が付けられます。 コミットオブジェクトはリンクリストのノードと考えることができます。 すべてのコミットオブジェクトには、親コミットオブジェクトへのポインタがあります。 特定のコミットから、親ポインターを見てコミットの履歴を表示することにより、前に戻ることができます。 コミットに複数の親コミットがある場合、その特定のコミットは2つのブランチをマージすることによって作成されています。

ブランチは、別の開発ラインを作成するために使用されます。 デフォルトでは、Gitにはmasterブランチがあります。これはSubversionのトランクと同じです。 通常、新しい機能で動作するブランチが作成されます。 機能が完成すると、それはmasterブランチにマージされ、ブランチを削除します。 すべてのブランチはHEADによって参照されます。HEADは、ブランチ内の最新のコミットを指します。 コミットを行うたびに、HEADは最新のコミットで更新されます。

Tags

タグは、リポジトリ内の特定のバージョンに意味のある名前を割り当てます。 タグはブランチに非常に似ていますが、違いはタグが不変であることです。 つまり、タグはブランチであり、誰も変更するつもりはありません。 特定のコミット用にタグが作成されると、新しいコミットを作成しても更新されません。 通常、開発者は製品リリース用のタグを作成します。

クローン

クローン操作により、リポジトリのインスタンスが作成されます。 クローン操作は、作業コピーをチェックアウトするだけでなく、リポジトリ全体をミラーリングします。 ユーザーは、このローカルリポジトリを使用して多くの操作を実行できます。 ネットワーキングが関係するのは、リポジトリインスタンスが同期されているときだけです。

Pull

プル操作は、リモートリポジトリインスタンスからローカルインスタンスに変更をコピーします。 プル操作は、2つのリポジトリインスタンス間の同期に使用されます。 これは、Subversionの更新操作と同じです。

Push

プッシュ操作は、ローカルリポジトリインスタンスからリモートインスタンスに変更をコピーします。 これは、変更をGitリポジトリに永続的に保存するために使用されます。 これは、Subversionのコミット操作と同じです。

HEAD

HEADはポインターであり、常にブランチの最新のコミットを指します。 コミットを行うたびに、HEADは最新のコミットで更新されます。 ブランチのヘッドは .git/refs/heads/ ディレクトリに保存されます。

[CentOS]$ ls -1 .git/refs/heads/
master

[CentOS]$ cat .git/refs/heads/master
570837e7d58fa4bccd86cb575d884502188b0c49

リビジョン

リビジョンは、ソースコードのバージョンを表します。 Gitのリビジョンはコミットによって表されます。 これらのコミットは、 SHA1 セキュアハッシュによって識別されます。

URL

URLはGitリポジトリの場所を表します。 Git URLは設定ファイルに保存されます。

[tom@CentOS tom_repo]$ pwd
/home/tom/tom_repo

[tom@CentOS tom_repo]$ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "origin"]
url = [email protected]:project.git
fetch = +refs/heads/*:refs/remotes/origin/*

Git-環境設定

Gitを使用する前に、いくつかの基本的な構成変更をインストールして実行する必要があります。 以下は、UbuntuおよびCentos LinuxにGitクライアントをインストールする手順です。

Gitクライアントのインストール

DebianベースのGNU/Linuxディストリビューションを使用している場合、 apt-get コマンドが必要なことを行います。

[ubuntu ~]$ sudo apt-get install git-core
[sudo] password for ubuntu:

[ubuntu ~]$ git --version
git version 1.8.1.2

RPMベースのGNU/Linuxディストリビューションを使用している場合は、 yum コマンドを指定どおりに使用してください。

[CentOS ~]$
su -
Password:

[CentOS ~]# yum -y install git-core

[CentOS ~]# git --version
git version 1.7.1

Git環境をカスタマイズする

Gitはgit configツールを提供します。これにより、構成変数を設定できます。 Gitはすべてのグローバル構成をホームディレクトリにある .gitconfig ファイルに保存します。 これらの構成値をグローバルとして設定するには、-global *オプションを追加し、-global *オプションを省略すると、構成は現在のGitリポジトリに固有になります。

システム全体の構成をセットアップすることもできます。 Gitはこれらの値を /etc/gitconfig ファイルに保存します。このファイルには、システム上のすべてのユーザーとリポジトリの構成が含まれています。 これらの値を設定するには、ルート権限があり、*-system *オプションを使用する必要があります。

上記のコードをコンパイルして実行すると、次の結果が生成されます-

ユーザー名を設定する

この情報は、コミットごとにGitによって使用されます。

[jerry@CentOS project]$ git config --global user.name "Jerry Mouse"

メールIDの設定

この情報は、コミットごとにGitによって使用されます。

[jerry@CentOS project]$ git config --global user.email "[email protected]"

プルのためのマージコミットを避ける

リモートリポジトリから最新の変更をプルし、これらの変更が異なる場合、デフォルトでGitはマージコミットを作成します。 これは次の設定で回避できます。

jerry@CentOS project]$ git config --global branch.autosetuprebase always

色の強調表示

次のコマンドは、コンソールでGitの色の強調表示を有効にします。

[jerry@CentOS project]$ git config --global color.ui true

[jerry@CentOS project]$ git config --global color.status auto

[jerry@CentOS project]$ git config --global color.branch auto

デフォルトのエディターの設定

デフォルトでは、Gitはシステムデフォルトエディターを使用します。これは、VISUALまたはEDITOR環境変数から取得されます。 git configを使用して別のものを構成できます。

[jerry@CentOS project]$ git config --global core.editor vim

デフォルトのマージツールの設定

Gitは、競合する変更を作業ツリーに統合するためのデフォルトのマージツールを提供しません。 次の設定を有効にすることで、デフォルトのマージツールを設定できます。

[jerry@CentOS project]$ git config --global merge.tool vimdiff

Git設定のリスト

ローカルリポジトリのGit設定を確認するには、以下に示すように git config –list コマンドを使用します。

[jerry@CentOS ~]$ git config --list

上記のコマンドは、次の結果を生成します。

user.name=Jerry Mouse
[email protected]
push.default=nothing
branch.autosetuprebase=always
color.ui=true
color.status=auto
color.branch=auto
core.editor=vim
merge.tool=vimdiff

Git-ライフサイクル

この章では、Gitのライフサイクルについて説明します。 後の章で、各操作のGitコマンドについて説明します。

一般的なワークフローは次のとおりです-

  • Gitリポジトリを作業コピーとして複製します。
  • ファイルを追加/編集して作業コピーを変更します。
  • 必要に応じて、他の開発者の変更を取得して作業コピーも更新します。
  • コミットする前に変更を確認します。
  • 変更をコミットします。 すべてが正常であれば、リポジトリに変更をプッシュします。
  • コミットした後、何かが間違っていることに気付いた場合は、最後のコミットを修正し、変更をリポジトリにプッシュします。

以下に、ワークフローの図式表現を示します。

Gitチュートリアル Git-create-operation

Git-クローン操作

Gitサーバーにベアリポジトリがあり、Tomも最初のバージョンをプッシュしました。 これで、ジェリーは自分の変更を表示できます。 クローン操作は、リモートリポジトリのインスタンスを作成します。

Jerryは、ホームディレクトリに新しいディレクトリを作成し、クローン操作を実行します。

[jerry@CentOS ~]$ mkdir jerry_repo

[jerry@CentOS ~]$ cd jerry_repo/

[jerry@CentOS jerry_repo]$ git clone [email protected]:project.git

上記のコマンドは、次の結果を生成します。

Initialized empty Git repository in/home/jerry/jerry_repo/project/.git/
remote: Counting objects: 3, done.
Receiving objects: 100% (3/3), 241 bytes, done.
remote: Total 3 (delta 0), reused 0 (delta 0)

Jerryはディレクトリを新しいローカルリポジトリに変更し、ディレクトリの内容をリストします。

[jerry@CentOS jerry_repo]$ cd project/

[jerry@CentOS jerry_repo]$ ls
README

Git-変更を実行

Jerryはリポジトリを複製し、基本的な文字列操作を実装することを決定します。 そこで彼はstring.cファイルを作成します。 内容を追加した後、string.cは次のようになります-

#include <stdio.h>

int my_strlen(char *s)
{
   char *p = s;

   while (*p)
      ++p;

   return (p - s);
}

int main(void)
{
   int i;
   char *s[] =
   {
      "Git tutorials",
      "Tutorials Point"
   };

   for (i = 0; i < 2; ++i)

   printf("string lenght of %s = %d\n", s[i], my_strlen(s[i]));

   return 0;
}

彼は自分のコードをコンパイルしてテストしましたが、すべて正常に動作しています。 これで、これらの変更をリポジトリに安全に追加できます。

Gitの追加操作により、ファイルがステージング領域に追加されます。

[jerry@CentOS project]$ git status -s
?? string
?? string.c

[jerry@CentOS project]$ git add string.c

Gitはファイル名の前に疑問符を表示しています。 明らかに、これらのファイルはGitの一部ではないため、Gitはこれらのファイルをどう処理するのか分からないのです。 そのため、Gitはファイル名の前に疑問符を表示しています。

Jerryはファイルをスタッシュ領域に追加しました。gitstatusコマンドはステージング領域に存在するファイルを表示します。

[jerry@CentOS project]$ git status -s
A string.c
?? string

変更をコミットするために、彼はgit commitコマンドの後に-mオプションを使用しました。 -mオプションを省略した場合。 Gitは、複数行のコミットメッセージを作成できるテキストエディターを開きます。

[jerry@CentOS project]$ git commit -m 'Implemented my_strlen function'

上記のコマンドは、次の結果を生成します-

[master cbe1249] Implemented my_strlen function
1 files changed, 24 insertions(+), 0 deletions(-)
create mode 100644 string.c

ログの詳細を表示することをコミットした後、彼はgit logコマンドを実行します。 コミットのすべての情報と、コミットID、コミットの作成者、コミット日、およびコミットの SHA-1 ハッシュが表示されます。

[jerry@CentOS project]$ git log

上記のコマンドは、次の結果を生成します-

commit cbe1249b140dad24b2c35b15cc7e26a6f02d2277
Author: Jerry Mouse <[email protected]>
Date: Wed Sep 11 08:05:26 2013 +0530

Implemented my_strlen function


commit 19ae20683fc460db7d127cf201a1429523b0e319
Author: Tom Cat <[email protected]>
Date: Wed Sep 11 07:32:56 2013 +0530

Initial commit

Git-変更のレビュー

コミットの詳細を表示した後、Jerryは文字列の長さを負にできないことを認識しているため、my_strlen関数の戻り値の型を変更することにしました。

Jerryは git log コマンドを使用してログの詳細を表示します。

[jerry@CentOS project]$ git log

上記のコマンドは、次の結果を生成します。

commit cbe1249b140dad24b2c35b15cc7e26a6f02d2277
Author: Jerry Mouse <[email protected]>
Date: Wed Sep 11 08:05:26 2013 +0530

Implemented my_strlen function

Jerryは git show コマンドを使用して、コミットの詳細を表示します。 git showコマンドは、パラメーターとして SHA-1 コミットIDを取ります。

[jerry@CentOS project]$ git show cbe1249b140dad24b2c35b15cc7e26a6f02d2277

上記のコマンドは、次の結果を生成します-

commit cbe1249b140dad24b2c35b15cc7e26a6f02d2277
Author: Jerry Mouse <[email protected]>
Date: Wed Sep 11 08:05:26 2013 +0530

Implemented my_strlen function


diff --git a/string.c b/string.c
new file mode 100644
index 0000000..187afb9
---/dev/null
+++ b/string.c
@@ -0,0 +1,24 @@
+#include <stdio.h>

+int my_strlen(char *s)
+{

   char *p = s;


   while (*p)
   + ++p;
   + return (p -s );

}

彼は、関数の戻り値の型をintからsize_tに変更します。 コードをテストした後、彼は git diff コマンドを実行して変更をレビューします。

[jerry@CentOS project]$ git diff

上記のコマンドは、次の結果を生成します-

diff --git a/string.c b/string.c
index 187afb9..7da2992 100644
--- a/string.c
+++ b/string.c
@@ -1,6 +1,6 @@
#include <stdio.h>

-int my_strlen(char *s)
+size_t my_strlen(char *s)
{
   char *p = s;
   @@ -18,7 +18,7 @@ int main(void)
};
for (i = 0; i < 2; ++i)
{
   - printf("string lenght of %s = %d\n", s[i], my_strlen(s[i]));
   + printf("string lenght of %s = %lu\n", s[i], my_strlen(s[i]));
   return 0;
}

Git diffでは、新しく追加される行の前に '+' 記号が表示され、削除された行には '-' が表示されます。

Git-変更のコミット

ジェリーはすでに変更をコミットしており、最後のコミットを修正したいと考えています。 この場合、 git amend 操作が役立ちます。 修正操作は、コミットメッセージを含む最後のコミットを変更します。新しいコミットIDを作成します。

操作を修正する前に、彼はコミットログをチェックします。

[jerry@CentOS project]$ git log

上記のコマンドは、次の結果を生成します。

commit cbe1249b140dad24b2c35b15cc7e26a6f02d2277
Author: Jerry Mouse <[email protected]>
Date: Wed Sep 11 08:05:26 2013 +0530

Implemented my_strlen function


commit 19ae20683fc460db7d127cf201a1429523b0e319
Author: Tom Cat <[email protected]>
Date: Wed Sep 11 07:32:56 2013 +0530

Initial commit

Jerryは新しい変更を-修正操作でコミットし、コミットログを表示します。

[jerry@CentOS project]$ git status -s
M string.c
?? string

[jerry@CentOS project]$ git add string.c

[jerry@CentOS project]$ git status -s
M string.c
?? string

[jerry@CentOS project]$ git commit --amend -m 'Changed return type of my_strlen to size_t'
[master d1e19d3] Changed return type of my_strlen to size_t
1 files changed, 24 insertions(+), 0 deletions(-)
create mode 100644 string.c

これで、gitログには新しいコミットIDを持つ新しいコミットメッセージが表示されます-

[jerry@CentOS project]$ git log

上記のコマンドは、次の結果を生成します。

commit d1e19d316224cddc437e3ed34ec3c931ad803958
Author: Jerry Mouse <[email protected]>
Date: Wed Sep 11 08:05:26 2013 +0530

Changed return type of my_strlen to size_t


commit 19ae20683fc460db7d127cf201a1429523b0e319
Author: Tom Cat <[email protected]>
Date: Wed Sep 11 07:32:56 2013 +0530

Initial commit

Git-プッシュ操作

Jerryは、修正操作を使用して最後のコミットを変更し、変更をプッシュする準備ができました。 プッシュ操作は、Gitリポジトリにデータを永続的に保存します。 プッシュ操作が成功すると、他の開発者はJerryの変更を確認できます。

彼はgit logコマンドを実行して、コミットの詳細を表示します。

[jerry@CentOS project]$ git log

上記のコマンドは、次の結果を生成します。

commit d1e19d316224cddc437e3ed34ec3c931ad803958
Author: Jerry Mouse <[email protected]>
Date: Wed Sep 11 08:05:26 2013 +0530

Changed return type of my_strlen to size_t

プッシュ操作の前に、彼は変更を確認したいので、 git show コマンドを使用して変更を確認します。

[jerry@CentOS project]$ git show d1e19d316224cddc437e3ed34ec3c931ad803958

上記のコマンドは、次の結果を生成します。

commit d1e19d316224cddc437e3ed34ec3c931ad803958
Author: Jerry Mouse <[email protected]>
Date: Wed Sep 11 08:05:26 2013 +0530

Changed return type of my_strlen to size_t

diff --git a/string.c b/string.c
new file mode 100644
index 0000000..7da2992
---/dev/null
+++ b/string.c
@@ -0,0 +1,24 @@
+#include <stdio.h>

+size_t my_strlen(char *s)

{

   char *p = s;


   while (*p)
   + ++p;
   + return (p -s );

}

+int main(void)

{
   + int i;
   + char *s[] =
   {
      + "Git tutorials",
      + "Tutorials Point"

   };



   for (i = 0; i < 2; ++i)
   printf("string lenght of %s = %lu\n", s[i], my_strlen(s[i]));


   return 0;

}

ジェリーは自分の変更に満足しており、変更をプッシュする準備ができています。

[jerry@CentOS project]$ git push origin master

上記のコマンドは、次の結果を生成します。

Counting objects: 4, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 517 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To [email protected]:project.git
19ae206..d1e19d3 master −> master

Jerryの変更がリポジトリに正常にプッシュされました。現在、他の開発者はクローンまたは更新操作を実行して自分の変更を表示できます。

Git-更新操作

既存の機能を変更

トムはクローン操作を実行し、新しいファイルstring.cを見つけます。 彼は誰がこのファイルをリポジトリに追加したか、どのような目的で追加したかを知りたいので、 git log コマンドを実行します。

[tom@CentOS ~]$ git clone [email protected]:project.git

上記のコマンドは、次の結果を生成します-

Initialized empty Git repository in/home/tom/project/.git/
remote: Counting objects: 6, done.
remote: Compressing objects: 100% (4/4), done.
Receiving objects: 100% (6/6), 726 bytes, done.
remote: Total 6 (delta 0), reused 0 (delta 0)

クローン操作により、現在の作業ディレクトリ内に新しいディレクトリが作成されます。 彼はディレクトリを新しく作成したディレクトリに変更し、 git log コマンドを実行します。

[tom@CentOS ~]$ cd project/

[tom@CentOS project]$ git log

上記のコマンドは、次の結果を生成します-

commit d1e19d316224cddc437e3ed34ec3c931ad803958
Author: Jerry Mouse <[email protected]>
Date: Wed Sep 11 08:05:26 2013 +0530

Changed return type of my_strlen to size_t


commit 19ae20683fc460db7d127cf201a1429523b0e319
Author: Tom Cat <[email protected]>
Date: Wed Sep 11 07:32:56 2013 +0530

Initial commit

ログを観察した後、彼はファイルstring.cが基本的な文字列操作を実装するためにJerryによって追加されたことに気付きました。 彼はジェリーのコードに興味があります。 そこで、彼はstring.cをテキストエディターで開き、すぐにバグを見つけます。 my_strlen関数では、Jerryは定数ポインターを使用していません。 そこで、彼はジェリーのコードを変更することにしました。 変更後、コードは次のようになります-

[tom@CentOS project]$ git diff

上記のコマンドは、次の結果を生成します-

diff --git a/string.c b/string.c
index 7da2992..32489eb 100644
--- a/string.c
+++ b/string.c
@@ -1,8 +1,8 @@
#include <stdio.h>
-size_t my_strlen(char *s)
+size_t my_strlen(const char *s)
{
   - char *p = s;
   + const char *p = s;
   while (*p)
   ++p;
}

テスト後、彼は変更をコミットします。

[tom@CentOS project]$ git status -s
M string.c
?? string

[tom@CentOS project]$ git add string.c

[tom@CentOS project]$ git commit -m 'Changed char pointer to const char pointer'
[master cea2c00] Changed char pointer to const char pointer
1 files changed, 2 insertions(+), 2 deletions(-)

[tom@CentOS project]$ git log

上記のコマンドは、次の結果を生成します-

commit cea2c000f53ba99508c5959e3e12fff493b
Author: Tom Cat <[email protected]>
Date: Wed Sep 11 08:32:07 2013 +0530

Changed char pointer to const char pointer


commit d1e19d316224cddc437e3ed34ec3c931ad803958
Author: Jerry Mouse <[email protected]>
Date: Wed Sep 11 08:05:26 2013 +0530

Changed return type of my_strlen to size_t


commit 19ae20683fc460db7d127cf201a1429523b0e319
Author: Tom Cat <[email protected]>
Date: Wed Sep 11 07:32:56 2013 +0530
Initial commit

トムはgit pushコマンドを使用して変更をプッシュします。

[tom@CentOS project]$ git push origin master

上記のコマンドは、次の結果を生成します-

Counting objects: 5, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 336 bytes, done.
Total 3 (delta 1), reused 0 (delta 0)
To [email protected]:project.git
d1e19d3..cea2c00 master −> master

新しい機能を追加

一方、Jerryは string compare 機能を実装することにしました。 そこで彼はstring.cを変更します。 変更後、ファイルは次のようになります-

[jerry@CentOS project]$ git diff

上記のコマンドは、次の結果を生成します-

index 7da2992..bc864ed 100644
--- a/string.c
+++ b/string.c
30Git Tutorials
@@ -9,9 +9,20 @@ size_t my_strlen(char *s)
return (p -s );
}
+char *my_strcpy(char *t, char *s)

{

   char *p = t;

   + while (*t++ = *s++)
   + ;


   return p;

}

int main(void)
{
   int i;

   char p1[32];
   char *s[] =
   {
      "Git tutorials",
      "Tutorials Point"
      @@ -20,5 +31,7 @@ int main(void)
      for (i = 0; i < 2; ++i)
      printf("string lenght of %s = %lu\n", s[i], my_strlen(s[i]));

      printf("%s\n", my_strcpy(p1, "Hello, World !!!"));

      return 0;
   }
}

テスト後、彼は変更をプッシュする準備ができています。

[jerry@CentOS project]$ git status -s
M string.c
?? string

[jerry@CentOS project]$ git add string.c

[jerry@CentOS project]$ git commit -m "Added my_strcpy function"
[master e944e5a] Added my_strcpy function
1 files changed, 13 insertions(+), 0 deletions(-)

プッシュ操作の前に、ログメッセージを表示してコミットを確認します。

[jerry@CentOS project]$ git log

上記のコマンドは、次の結果を生成します-

commit e944e5aab74b26e7447d3281b225309e4e59efcd
Author: Jerry Mouse <[email protected]>
Date: Wed Sep 11 08:41:42 2013 +0530

Added my_strcpy function


commit d1e19d316224cddc437e3ed34ec3c931ad803958
Author: Jerry Mouse <[email protected]>
Date: Wed Sep 11 08:05:26 2013 +0530

Changed return type of my_strlen to size_t


commit 19ae20683fc460db7d127cf201a1429523b0e319
Author: Tom Cat <[email protected]>
Date: Wed Sep 11 07:32:56 2013 +0530

Initial commit

ジェリーは変更に満足しており、変更をプッシュしたいと考えています。

[jerry@CentOS project]$ git push origin master

上記のコマンドは、次の結果を生成します-

To [email protected]:project.git
! [rejected]
master −> master (non-fast-forward)
error: failed to push some refs to '[email protected]:project.git'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes before pushing again. See the 'Note about
fast-forwards' section of 'git push --help' for details.

しかし、GitはJerryが変更をプッシュすることを許可していません。 Gitは、リモートリポジトリとJerryのローカルリポジトリが同期していないと判断したためです。 このため、彼はプロジェクトの歴史を失う可能性があります。 この混乱を避けるため、Gitはこの操作に失敗しました。 現在、ジェリーは最初にローカルリポジトリを更新する必要があり、その後のみ、自分の変更をプッシュできます。

最新の変更を取得する

Jerryはgit pullコマンドを実行して、ローカルリポジトリをリモートリポジトリと同期します。

[jerry@CentOS project]$ git pull

上記のコマンドは、次の結果を生成します-

remote: Counting objects: 5, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From git.server.com:project
d1e19d3..cea2c00 master −> origin/master
First, rewinding head to replay your work on top of it...
Applying: Added my_strcpy function

プル操作の後、ジェリーはログメッセージをチェックし、コミットID cea2c000f53ba99508c5959e3e12fff493ba6f69 を持つトムのコミットの詳細を見つけます。

[jerry@CentOS project]$ git log

上記のコマンドは、次の結果を生成します-

commit e86f0621c2a3f68190bba633a9fe6c57c94f8e4f
Author: Jerry Mouse <[email protected]>
Date: Wed Sep 11 08:41:42 2013 +0530

Added my_strcpy function


commit cea2c000f53ba99508c5959e3e12fff493ba6f69
Author: Tom Cat <[email protected]>
Date: Wed Sep 11 08:32:07 2013 +0530

Changed char pointer to const char pointer


commit d1e19d316224cddc437e3ed34ec3c931ad803958
Author: Jerry Mouse <[email protected]>
Date: Wed Sep 11 08:05:26 2013 +0530

Changed return type of my_strlen to size_t


commit 19ae20683fc460db7d127cf201a1429523b0e319
Author: Tom Cat <[email protected]>
Date: Wed Sep 11 07:32:56 2013 +0530
Initial commit

現在、Jerryのローカルリポジトリはリモートリポジトリと完全に同期されています。 したがって、彼は変更を安全にプッシュできます。

[jerry@CentOS project]$ git push origin master

上記のコマンドは、次の結果を生成します-

Counting objects: 5, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 455 bytes, done.
Total 3 (delta 1), reused 0 (delta 0)
To [email protected]:project.git
cea2c00..e86f062 master −> master

Git-スタッシュ操作

製品に新しい機能を実装するとします。 コードが進行中で、突然顧客のエスカレーションが発生します。 このため、数時間は新しい機能の作業を脇に置いておく必要があります。 部分的なコードをコミットしたり、変更を破棄したりすることはできません。 そのため、部分的な変更を保存し、後でコミットするための一時スペースが必要です。

Gitでは、stash操作は変更された追跡ファイルを取得し、変更をステージングし、いつでも再適用できる未完成の変更のスタックに保存します。

[jerry@CentOS project]$ git status -s
M string.c
?? string

ここで、顧客のエスカレーションのためにブランチを切り替えたいが、まだ取り組んでいるものをコミットしたくない。そのため、変更を隠しておきます。 新しいスタッシュをスタックにプッシュするには、 git stash コマンドを実行します。

[jerry@CentOS project]$ git stash
Saved working directory and index state WIP on master: e86f062 Added my_strcpy function
HEAD is now at e86f062 Added my_strcpy function

これで、作業ディレクトリがクリーンになり、すべての変更がスタックに保存されます。 git status コマンドで確認しましょう。

[jerry@CentOS project]$ git status -s
?? string

これで、ブランチを安全に切り替えて他の場所で作業できます。 git stash list コマンドを使用して、隠された変更のリストを表示できます。

[jerry@CentOS project]$ git stash list
stash@{0}: WIP on master: e86f062 Added my_strcpy function

顧客のエスカレーションを解決し、半分完了したコードを探して新しい機能に戻ったとします。 git stash pop コマンドを実行して、スタックから変更を削除し、現在の作業ディレクトリに配置します。

[jerry@CentOS project]$ git status -s
?? string

[jerry@CentOS project]$ git stash pop

上記のコマンドは、次の結果を生成します。

# On branch master
# Changed but not updated:
# (use "git add ..." to update what will be committed)
# (use "git checkout -- ..." to discard changes in working directory)
#
#
modified: string.c
#
# Untracked files:
# (use "git add ..." to include in what will be committed)
#
#
string
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (36f79dfedae4ac20e2e8558830154bd6315e72d4)

[jerry@CentOS project]$ git status -s
M string.c
?? string

Git-移動操作

名前が示すように、移動操作はディレクトリまたはファイルをある場所から別の場所に移動します。 トムは、ソースコードを src ディレクトリに移動することにしました。 変更されたディレクトリ構造は次のように表示されます-

[tom@CentOS project]$ pwd
/home/tom/project

[tom@CentOS project]$ ls
README string string.c

[tom@CentOS project]$ mkdir src

[tom@CentOS project]$ git mv string.c src/

[tom@CentOS project]$ git status -s
R string.c −> src/string.c
?? string

これらの変更を永続的にするには、変更されたディレクトリ構造をリモートリポジトリにプッシュして、他の開発者がこれを確認できるようにする必要があります。

[tom@CentOS project]$ git commit -m "Modified directory structure"

[master 7d9ea97] Modified directory structure
1 files changed, 0 insertions(+), 0 deletions(-)
rename string.c => src/string.c (100%)

[tom@CentOS project]$ git push origin master
Counting objects: 4, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 320 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To [email protected]:project.git
e86f062..7d9ea97 master −> master

Jerryのローカルリポジトリでは、プル操作の前に、古いディレクトリ構造が表示されます。

[jerry@CentOS project]$ pwd
/home/jerry/jerry_repo/project

[jerry@CentOS project]$ ls
README string string.c

ただし、プル操作の後、ディレクトリ構造は更新されます。 これで、Jerryは src ディレクトリとそのディレクトリ内にあるファイルを見ることができます。

[jerry@CentOS project]$ git pull
remote: Counting objects: 4, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From git.server.com:project
e86f062..7d9ea97 master −> origin/master
First, rewinding head to replay your work on top of it...
Fast-forwarded master to 7d9ea97683da90bcdb87c28ec9b4f64160673c8a.

[jerry@CentOS project]$ ls
README src string

[jerry@CentOS project]$ ls src/
string.c

Git-操作の名前変更

今まで、トムとジェリーの両方がプロジェクトをコンパイルするために手動コマンドを使用していました。 現在、ジェリーはプロジェクト用にMakefileを作成し、ファイル「string.c」に適切な名前を付けることにしました。

[jerry@CentOS project]$ pwd
/home/jerry/jerry_repo/project

[jerry@CentOS project]$ ls
README src

[jerry@CentOS project]$ cd src/

[jerry@CentOS src]$ git add Makefile

[jerry@CentOS src]$ git mv string.c string_operations.c

[jerry@CentOS src]$ git status -s
A Makefile
R string.c −> string_operations.c

Gitはファイル名の前に R を表示して、ファイルの名前が変更されたことを示しています。

コミット操作では、Jerryは-aフラグを使用しました。これにより、git commitは変更されたファイルを自動的に検出します。

[jerry@CentOS src]$ git commit -a -m 'Added Makefile and renamed strings.c to
string_operations.c '

[master 94f7b26] Added Makefile and renamed strings.c to string_operations.c
1 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 src/Makefile
rename src/{string.c => string_operations.c} (100%)

コミット後、彼は自分の変更をリポジトリにプッシュします。

[jerry@CentOS src]$ git push origin master

上記のコマンドは、次の結果を生成します-

Counting objects: 6, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 396 bytes, done.
Total 4 (delta 0), reused 0 (delta 0)
To [email protected]:project.git
7d9ea97..94f7b26 master −> master

現在、他の開発者は、ローカルリポジトリを更新することでこれらの変更を表示できます。

Git-削除操作

トムは自分のローカルリポジトリを更新し、 src ディレクトリでコンパイルされたバイナリを見つけます。 コミットメッセージを表示した後、彼はコンパイルされたバイナリがJerryによって追加されたことに気付きます。

[tom@CentOS src]$ pwd
/home/tom/project/src

[tom@CentOS src]$ ls
Makefile string_operations string_operations.c

[tom@CentOS src]$ file string_operations
string_operations: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses
shared libs), for GNU/Linux 2.6.18, not stripped

[tom@CentOS src]$ git log
commit 29af9d45947dc044e33d69b9141d8d2dad37cc62
Author: Jerry Mouse <[email protected]>
Date: Wed Sep 11 10:16:25 2013 +0530

Added compiled binary

VCSは、実行可能バイナリではなく、ソースコードのみを格納するために使用されます。 そこで、トムはこのファイルをリポジトリから削除することにしました。 さらに操作するために、彼は git rm コマンドを使用します。

[tom@CentOS src]$ ls
Makefile string_operations string_operations.c

[tom@CentOS src]$ git rm string_operations
rm 'src/string_operations'

[tom@CentOS src]$ git commit -a -m "Removed executable binary"

[master 5776472] Removed executable binary
1 files changed, 0 insertions(+), 0 deletions(-)
delete mode 100755 src/string_operations

コミット後、彼は自分の変更をリポジトリにプッシュします。

[tom@CentOS src]$ git push origin master

上記のコマンドは、次の結果を生成します。

Counting objects: 5, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 310 bytes, done.
Total 3 (delta 1), reused 0 (delta 0)
To [email protected]:project.git
29af9d4..5776472 master −> master

Git-間違いを修正

誤ることは人間です。 そのため、すべてのVCSは、特定のポイントまでミスを修正する機能を提供します。 Gitは、ローカルリポジトリに加えられた変更を取り消すために使用できる機能を提供します。

ユーザーがローカルリポジトリに誤って変更を加えた後、これらの変更を元に戻したいとします。 このような場合、 revert 操作が重要な役割を果たします。

コミットされていない変更を元に戻す

Jerryがローカルリポジトリのファイルを誤って変更したとします。 しかし、彼は変更を元に戻したいと考えています。 この状況に対処するには、 git checkout コマンドを使用できます。 このコマンドを使用して、ファイルの内容を元に戻すことができます。

[jerry@CentOS src]$ pwd
/home/jerry/jerry_repo/project/src

[jerry@CentOS src]$ git status -s
M string_operations.c

[jerry@CentOS src]$ git checkout string_operations.c

[jerry@CentOS src]$ git status –s

さらに、 git checkout コマンドを使用して、ローカルリポジトリから削除されたファイルを取得できます。 トムがローカルリポジトリからファイルを削除し、このファイルを元に戻したいとします。 同じコマンドを使用してこれを実現できます。

[tom@CentOS src]$ pwd
/home/tom/top_repo/project/src

[tom@CentOS src]$ ls -1
Makefile
string_operations.c

[tom@CentOS src]$ rm string_operations.c

[tom@CentOS src]$ ls -1
Makefile

[tom@CentOS src]$ git status -s
D string_operations.c

Gitはファイル名の前に D という文字を表示しています。 これは、ファイルがローカルリポジトリから削除されたことを示します。

[tom@CentOS src]$ git checkout string_operations.c

[tom@CentOS src]$ ls -1
Makefile
string_operations.c

[tom@CentOS src]$ git status -s

注意-コミットする前にこれらすべての操作を実行できます。

ステージング領域から変更を削除

追加操作を実行すると、ファイルがローカルリポジトリから開始領域に移動することがわかりました。 ユーザーが誤ってファイルを変更してステージング領域に追加した場合、 git checkout コマンドを使用して、変更を元に戻すことができます。

Gitには、常に最新のコミットを指す1つのHEADポインターがあります。 ステージング領域からの変更を取り消す場合は、git checkoutコマンドを使用できますが、checkoutコマンドでは、追加のパラメーター、つまりHEADポインターを指定する必要があります。 追加のコミットポインターパラメーターは、git checkoutコマンドに作業ツリーをリセットし、段階的な変更を削除するよう指示します。

トムがローカルリポジトリからファイルを変更するとします。 このファイルのステータスを表示すると、ファイルが変更されたがステージング領域に追加されていないことがわかります。

tom@CentOS src]$ pwd
/home/tom/top_repo/project/src
# Unmodified file

[tom@CentOS src]$ git status -s

# Modify file and view it’s status.
[tom@CentOS src]$ git status -s
M string_operations.c

[tom@CentOS src]$ git add string_operations.c

Gitステータスは、ファイルがステージング領域に存在することを示しています。現在は、git checkoutコマンドを使用してファイルを元に戻し、元に戻したファイルのステータスを表示します。

[tom@CentOS src]$ git checkout HEAD -- string_operations.c

[tom@CentOS src]$ git status -s

GitリセットでHEADポインターを移動する

いくつかの変更を行った後、これらの変更を削除することができます。 Gitリセットコマンドは、変更をリセットまたは元に戻すために使用されます。 3種類のリセット操作を実行できます。

以下の図は、Gitリセットコマンドの図的表現を示しています。

gitチュートリアル gitチュートリアル

Soft

各ブランチには、最新のコミットを指すHEADポインターがあります。 --softオプションの後にコミットIDを指定してGitのリセットコマンドを使用すると、何も破壊せずにHEADポインターのみがリセットされます。

*.git/refs/heads/master* ファイルには、HEADポインターのコミットIDが格納されます。 *git log -1* コマンドを使用して確認できます。
[jerry@CentOS project]$ cat .git/refs/heads/master
577647211ed44fe2ae479427a0668a4f12ed71a1

ここで、上記のコミットIDと一致する最新のコミットIDを表示します。

[jerry@CentOS project]$ git log -2

上記のコマンドは、次の結果を生成します。

commit 577647211ed44fe2ae479427a0668a4f12ed71a1
Author: Tom Cat <[email protected]>
Date: Wed Sep 11 10:21:20 2013 +0530

Removed executable binary


commit 29af9d45947dc044e33d69b9141d8d2dad37cc62
Author: Jerry Mouse <[email protected]>
Date: Wed Sep 11 10:16:25 2013 +0530

Added compiled binary

HEADポインターをリセットしましょう。

[jerry@CentOS project]$ git reset --soft HEAD~

ここで、HEADポインターを1ポジションだけリセットします。 .git/refs/heads/master file の内容を確認しましょう。

[jerry@CentOS project]$ cat .git/refs/heads/master
29af9d45947dc044e33d69b9141d8d2dad37cc62

ファイルのコミットIDが変更されました。コミットメッセージを表示して確認してください。

jerry@CentOS project]$ git log -2

上記のコマンドは、次の結果を生成します。

commit 29af9d45947dc044e33d69b9141d8d2dad37cc62
Author: Jerry Mouse <[email protected]>
Date: Wed Sep 11 10:16:25 2013 +0530

Added compiled binary


commit 94f7b26005f856f1a1b733ad438e97a0cd509c1a
Author: Jerry Mouse <[email protected]>
Date: Wed Sep 11 10:08:01 2013 +0530

Added Makefile and renamed strings.c to string_operations.c

混合した

--mixedオプションを使用してGitをリセットすると、まだコミットされていないステージング領域からの変更が元に戻されます。 ステージング領域からの変更のみを元に戻します。 ファイルの作業コピーに加えられた実際の変更は影響を受けません。 デフォルトのGitリセットはgit reset --mixedと同等です。

hard

Gitリセットコマンドで—​hardオプションを使用すると、ステージング領域がクリアされます。 HEADポインターを特定のコミットIDの最新のコミットにリセットし、ローカルファイルの変更も削除します。

コミットIDを確認しましょう。

[jerry@CentOS src]$ pwd
/home/jerry/jerry_repo/project/src

[jerry@CentOS src]$ git log -1

上記のコマンドは、次の結果を生成します。

commit 577647211ed44fe2ae479427a0668a4f12ed71a1
Author: Tom Cat <[email protected]>
Date: Wed Sep 11 10:21:20 2013 +0530

Removed executable binary

Jerryは、ファイルの先頭に1行のコメントを追加してファイルを変更しました。

[jerry@CentOS src]$ head -2 string_operations.c
/*This line be removed by git reset operation*/
#include <stdio.h>

彼はgit statusコマンドを使用してそれを検証しました。

[jerry@CentOS src]$ git status -s
M string_operations.c

Jerryは変更されたファイルをステージング領域に追加し、git statusコマンドで検証します。

[jerry@CentOS src]$ git add string_operations.c
[jerry@CentOS src]$ git status

上記のコマンドは、次の結果を生成します。

# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
#
modified: string_operations.c
#

Gitステータスは、ファイルがステージング領域に存在することを示しています。 次に、--hardオプションでHEADをリセットします。

[jerry@CentOS src]$ git reset --hard 577647211ed44fe2ae479427a0668a4f12ed71a1

HEAD is now at 5776472 Removed executable binary

Gitリセットコマンドが成功しました。これにより、ファイルがステージング領域から戻され、ファイルに加えられたローカルの変更がすべて削除されます。

[jerry@CentOS src]$ git status -s

Gitステータスは、ファイルがステージング領域から元に戻されたことを示しています。

[jerry@CentOS src]$ head -2 string_operations.c
#include <stdio.h>

また、headコマンドは、リセット操作によってローカルの変更も削除されたことを示しています。

Git-タグ操作

タグ操作により、リポジトリ内の特定のバージョンに意味のある名前を付けることができます。 トムとジェリーがプロジェクトコードにタグを付けて、後で簡単にアクセスできるようにするとします。

タグを作成する

*git tag* コマンドを使用して、現在のHEADにタグを付けましょう。 トムは、-aオプションでタグ名を提供し、-mオプションでタグメッセージを提供します。
tom@CentOS project]$ pwd
/home/tom/top_repo/project

[tom@CentOS project]$ git tag -a 'Release_1_0' -m 'Tagged basic string operation code' HEAD

特定のコミットにタグを付ける場合は、HEADポインターの代わりに適切なCOMMIT IDを使用します。 トムは次のコマンドを使用して、タグをリモートリポジトリにプッシュします。

[tom@CentOS project]$ git push origin tag Release_1_0

上記のコマンドは、次の結果を生成します-

Counting objects: 1, done.
Writing objects: 100% (1/1), 183 bytes, done.
Total 1 (delta 0), reused 0 (delta 0)
To [email protected]:project.git
* [new tag]
Release_1_0 −> Release_1_0

タグを表示

トムはタグを作成しました。 これで、Jerryは、-lオプションを指定したGit tagコマンドを使用して、使用可能なすべてのタグを表示できます。

[jerry@CentOS src]$ pwd
/home/jerry/jerry_repo/project/src

[jerry@CentOS src]$ git pull
remote: Counting objects: 1, done.
remote: Total 1 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (1/1), done.
From git.server.com:project
* [new tag]
Release_1_0 −> Release_1_0
Current branch master is up to date.

[jerry@CentOS src]$ git tag -l
Release_1_0

Jerryは、Gitのshowコマンドの後にタグ名を使用して、タグの詳細を表示します。

[jerry@CentOS src]$ git show Release_1_0

上記のコマンドは、次の結果を生成します-

tag Release_1_0
Tagger: Tom Cat <[email protected]>
Date: Wed Sep 11 13:45:54 2013 +0530

Tagged basic string operation code


commit 577647211ed44fe2ae479427a0668a4f12ed71a1
Author: Tom Cat <[email protected]>
Date: Wed Sep 11 10:21:20 2013 +0530

Removed executable binary

diff --git a/src/string_operations b/src/string_operations
deleted file mode 100755
index 654004b..0000000
Binary files a/src/string_operations and/dev/null differ

タグを削除

トムは次のコマンドを使用して、ローカルおよびリモートのリポジトリからタグを削除します。

[tom@CentOS project]$ git tag
Release_1_0

[tom@CentOS project]$ git tag -d Release_1_0
Deleted tag 'Release_1_0' (was 0f81ff4)
# Remove tag from remote repository.

[tom@CentOS project]$ git push origin :Release_1_0
To [email protected]:project.git
- [deleted]
Release_1_0

Git-パッチ操作

パッチはテキストファイルで、その内容はGit diffと似ていますが、コードとともに、コミットに関するメタデータも含まれています。例:コミットID、日付、コミットメッセージなど コミットからパッチを作成でき、他の人はそれらをリポジトリに適用できます。

Jerryは彼のプロジェクトにstrcat関数を実装しています。 Jerryは自分のコードのパスを作成して、Tomに送信できます。 次に、受け取ったパッチを自分のコードに適用できます。

JerryはGit format-patch コマンドを使用して、最新のコミット用のパッチを作成します。 特定のコミット用のパッチを作成する場合は、format-patchコマンドで COMMIT_ID を使用します。

[jerry@CentOS project]$ pwd
/home/jerry/jerry_repo/project/src

[jerry@CentOS src]$ git status -s
M string_operations.c
?? string_operations

[jerry@CentOS src]$ git add string_operations.c

[jerry@CentOS src]$ git commit -m "Added my_strcat function"

[master b4c7f09] Added my_strcat function
1 files changed, 13 insertions(+), 0 deletions(-)

[jerry@CentOS src]$ git format-patch -1
0001-Added-my_strcat-function.patch

上記のコマンドは、現在の作業ディレクトリ内に .patch ファイルを作成します。 トムはこのパッチを使用してファイルを変更できます。 Gitは、パッチ* git am および *git apply をそれぞれ適用する2つのコマンドを提供します。 Git apply はコミットを作成せずにローカルファイルを変更し、 git am はファイルを変更してコミットも作成します。

パッチを適用してコミットを作成するには、次のコマンドを使用します-

[tom@CentOS src]$ pwd
/home/tom/top_repo/project/src

[tom@CentOS src]$ git diff

[tom@CentOS src]$ git status –s

[tom@CentOS src]$ git apply 0001-Added-my_strcat-function.patch

[tom@CentOS src]$ git status -s
M string_operations.c
?? 0001-Added-my_strcat-function.patch

パッチが正常に適用されると、 git diff コマンドを使用して変更を表示できます。

[tom@CentOS src]$ git diff

上記のコマンドは、次の結果を生成します-

diff --git a/src/string_operations.c b/src/string_operations.c
index 8ab7f42..f282fcf 100644
--- a/src/string_operations.c
+++ b/src/string_operations.c
@@ -1,5 +1,16 @@
#include <stdio.h>
+char *my_strcat(char *t, char *s)
diff --git a/src/string_operations.c b/src/string_operations.c
index 8ab7f42..f282fcf 100644
--- a/src/string_operations.c
+++ b/src/string_operations.c
@@ -1,5 +1,16 @@
#include <stdio.h>
+char *my_strcat(char *t, char *s)

{

   char *p = t;



   while (*p)
   ++p;

   while (*p++ = *s++)
   + ;
   + return t;

}

size_t my_strlen(const char *s)
{
   const char *p = s;
   @@ -23,6 +34,7 @@ int main(void)
   {

Git-ブランチの管理

分岐操作により、別の開発ラインを作成できます。 この操作を使用して、開発プロセスを2つの異なる方向に分岐できます。 たとえば、6.0バージョンの製品をリリースし、7.0の機能の開発を6.0のバグ修正とは別に維持できるようにブランチを作成する場合があります。

ブランチを作成

トムは、git branch <branch name>コマンドを使用して新しいブランチを作成します。 既存のブランチから新しいブランチを作成できます。 特定のコミットまたはタグを開始点として使用できます。 特定のコミットIDが提供されていない場合、開始点としてHEADを使用してブランチが作成されます。

[jerry@CentOS src]$ git branch new_branch

[jerry@CentOS src]$ git branch
* master
new_branch

新しいブランチが作成されます。 Tomはgit branchコマンドを使用して、利用可能なブランチを一覧表示しました。 Gitは、現在チェックアウトされているブランチの前にアスタリスクマークを表示します。

ブランチ作成操作の図解は以下に示されています-

gitチュートリアル gitチュートリアル

ブランチを切り替える

Jerryはgit checkoutコマンドを使用してブランチを切り替えます。

[jerry@CentOS src]$ git checkout new_branch
Switched to branch 'new_branch'
[jerry@CentOS src]$ git branch
master
* new_branch

ブランチを作成して切り替えるためのショートカット

上記の例では、2つのコマンドを使用してそれぞれブランチを作成および切り替えています。 Gitはcheckoutコマンドで –b オプションを提供します。この操作により、新しいブランチが作成され、すぐに新しいブランチに切り替わります。

[jerry@CentOS src]$ git checkout -b test_branch
Switched to a new branch 'test_branch'

[jerry@CentOS src]$ git branch
master
new_branch
* test_branch

ブランチを削除する

ブランチを削除するには、git branchコマンドで-Dオプションを指定します。 ただし、既存のブランチを削除する前に、他のブランチに切り替えてください。

Jerryは現在 test_branch にいるので、そのブランチを削除したいと考えています。 そこで、彼は以下に示すようにブランチを切り替えてブランチを削除します。

[jerry@CentOS src]$ git branch
master
new_branch
* test_branch

[jerry@CentOS src]$ git checkout master
Switched to branch 'master'

[jerry@CentOS src]$ git branch -D test_branch
Deleted branch test_branch (was 5776472).

これで、Gitは2つのブランチのみを表示します。

[jerry@CentOS src]$ git branch
* master
new_branch

ブランチの名前を変更する

Jerryは、文字列操作プロジェクトでワイド文字のサポートを追加することにしました。 彼はすでに新しいブランチを作成していますが、ブランチ名は適切ではありません。 そのため、 – m オプションの後に* oldブランチ名*と* newブランチ名*を使用してブランチ名を変更します。

[jerry@CentOS src]$ git branch
* master
new_branch

[jerry@CentOS src]$ git branch -m new_branch wchar_support

これで、git branchコマンドは新しいブランチ名を表示します。

[jerry@CentOS src]$ git branch
* master
wchar_support

2つのブランチをマージする

Jerryは、ワイド文字列の文字列長を返す関数を実装しています。 新しいコードは次のように表示されます-

[jerry@CentOS src]$ git branch
master
 *wchar_support

[jerry@CentOS src]$ pwd
/home/jerry/jerry_repo/project/src

[jerry@CentOS src]$ git diff

上記のコマンドは、次の結果を生成します-

t a/src/string_operations.c b/src/string_operations.c
index 8ab7f42..8fb4b00 100644
--- a/src/string_operations.c
+++ b/src/string_operations.c
@@ -1,4 +1,14 @@
#include <stdio.h>
+#include <wchar.h>

+size_t w_strlen(const wchar_t* s)

{

   const wchar_t *p = s;


   while (*p)
   + ++p;
   + return (p - s);

}

テスト後、彼は変更をコミットして新しいブランチにプッシュします。

[jerry@CentOS src]$ git status -s
M string_operations.c
?? string_operations

[jerry@CentOS src]$ git add string_operations.c

[jerry@CentOS src]$ git commit -m 'Added w_strlen function to return string lenght of wchar_t
string'

[wchar_support 64192f9] Added w_strlen function to return string lenght of wchar_t string
1 files changed, 10 insertions(+), 0 deletions(-)

Jerryはこれらの変更を新しいブランチにプッシュしているため、 master ブランチの代わりにブランチ名 wchar_support を使用したことに注意してください。

[jerry@CentOS src]$ git push origin wchar_support   <−−− Observer branch_name

上記のコマンドは、次の結果を生成します。

Counting objects: 7, done.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 507 bytes, done.
Total 4 (delta 1), reused 0 (delta 0)
To [email protected]:project.git
* [new branch]
wchar_support -> wchar_support

変更をコミットした後、新しいブランチは次のように表示されます-

gitチュートリアル

トムは、ジェリーがプライベートブランチで何をしているのか興味があり、 wchar_support ブランチのログをチェックします。

[tom@CentOS src]$ pwd
/home/tom/top_repo/project/src

[tom@CentOS src]$ git log origin/wchar_support -2

上記のコマンドは、次の結果を生成します。

commit 64192f91d7cc2bcdf3bf946dd33ece63b74184a3
Author: Jerry Mouse <[email protected]>
Date: Wed Sep 11 16:10:06 2013 +0530

Added w_strlen function to return string lenght of wchar_t string


commit 577647211ed44fe2ae479427a0668a4f12ed71a1
Author: Tom Cat <[email protected]>
Date: Wed Sep 11 10:21:20 2013 +0530

Removed executable binary

コミットメッセージを表示することにより、トムはジェリーがワイドキャラクター用のstrlen関数を実装し、マスターブランチで同じ機能が必要であることを認識しています。 再実装する代わりに、彼はブランチをマスターブランチにマージして、ジェリーのコードを取ることにしました。

[tom@CentOS project]$ git branch
* master

[tom@CentOS project]$ pwd
/home/tom/top_repo/project

[tom@CentOS project]$ git merge origin/wchar_support
Updating 5776472..64192f9
Fast-forward
src/string_operations.c | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)

マージ操作の後、マスターブランチは次のように表示されます-

gitチュートリアル

これで、ブランチ wchar_support がmasterブランチにマージされました。 コミットメッセージを表示するか、string_operation.cファイルに加えられた変更を表示することで確認できます。

[tom@CentOS project]$ cd src/

[tom@CentOS src]$ git log -1

commit 64192f91d7cc2bcdf3bf946dd33ece63b74184a3
Author: Jerry Mouse
Date: Wed Sep 11 16:10:06 2013 +0530

Added w_strlen function to return string lenght of wchar_t string

[tom@CentOS src]$ head -12 string_operations.c

上記のコマンドは、次の結果を生成します。

#include <stdio.h>
#include <wchar.h>
size_t w_strlen(const wchar_t *s)
{
   const wchar_t *p = s;

   while (*p)
      ++p;

   return (p - s);
}

テスト後、彼はコードの変更をmasterブランチにプッシュします。

[tom@CentOS src]$ git push origin master
Total 0 (delta 0), reused 0 (delta 0)
To [email protected]:project.git
5776472..64192f9 master −> master

ブランチのリベース

Git rebaseコマンドはブランチマージコマンドですが、違いはコミットの順序を変更することです。

Git mergeコマンドは、他のブランチからのコミットを現在のローカルブランチのHEADの上に配置しようとします。 たとえば、ローカルブランチにコミットA→ B→ C→ Dがあり、マージブランチにコミットA→ B→ X→ Yがある場合、git mergeは現在のローカルブランチをA→のようなものに変換しますB→ C→ D→ X→ Y

Git rebaseコマンドは、現在のローカルブランチとマージブランチ間の共通の祖先を見つけようとします。 次に、現在のローカルブランチのコミットの順序を変更して、コミットをローカルブランチにプッシュします。 たとえば、ローカルブランチにコミットA→ B→ C→ Dがあり、マージブランチにコミットA→ B→ X→ Yがある場合、Gitリベースは現在のローカルブランチをA-のようなものに変換します> B→ X→ Y→ C→ D。

複数の開発者が単一のリモートリポジトリで作業する場合、リモートリポジトリ内のコミットの順序を変更することはできません。 この状況では、リベース操作を使用して、ローカルコミットをリモートリポジトリコミットの上に配置し、これらの変更をプッシュできます。

Git-競合の処理

wchar_supportブランチで変更を実行する

Jerryは wchar_support ブランチに取り組んでいます。 彼は関数の名前を変更し、テスト後に変更をコミットします。

[jerry@CentOS src]$ git branch
 master
 *wchar_support
[jerry@CentOS src]$ git diff

上記のコマンドは、次の結果を生成します-

diff --git a/src/string_operations.c b/src/string_operations.c
index 8fb4b00..01ff4e0 100644
--- a/src/string_operations.c
+++ b/src/string_operations.c
@@ -1,7 +1,7 @@
#include <stdio.h>
#include <wchar.h>
-size_t w_strlen(const wchar_t* s)
+size_t my_wstrlen(const wchar_t *s)
{
   const wchar_t *p = s;

コードを確認した後、彼は変更をコミットします。

[jerry@CentOS src]$ git status -s
M string_operations.c

[jerry@CentOS src]$ git add string_operations.c

[jerry@CentOS src]$ git commit -m 'Changed function name'
[wchar_support 3789fe8] Changed function name
1 files changed, 1 insertions(+), 1 deletions(-)

[jerry@CentOS src]$ git push origin wchar_support

上記のコマンドは、次の結果を生成します-

Counting objects: 7, done.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 409 bytes, done.
Total 4 (delta 1), reused 0 (delta 0)
To [email protected]:project.git
64192f9..3789fe8 wchar_support -> wchar_support

Master Branchで変更を実行する

一方、マスターブランチでは、トムは同じ関数の名前も変更し、変更をマスターブランチにプッシュします。

[tom@CentOS src]$ git branch
 *master
[tom@CentOS src]$ git diff

上記のコマンドは、次の結果を生成します-

diff --git a/src/string_operations.c b/src/string_operations.c
index 8fb4b00..52bec84 100644
--- a/src/string_operations.c
+++ b/src/string_operations.c
@@ -1,7 +1,8 @@
#include <stdio.h>
#include <wchar.h>
-size_t w_strlen(const wchar_t* s)
+/*wide character strlen fucntion*/
+size_t my_wc_strlen(const wchar_t *s)
{
   const wchar_t *p = s;

diffを検証した後、彼は変更をコミットします。

[tom@CentOS src]$ git status -s
M string_operations.c

[tom@CentOS src]$ git add string_operations.c

[tom@CentOS src]$ git commit -m 'Changed function name from w_strlen to my_wc_strlen'
[master ad4b530] Changed function name from w_strlen to my_wc_strlen
1 files changed, 2 insertions(+), 1 deletions(-)

[tom@CentOS src]$ git push origin master

上記のコマンドは、次の結果を生成します-

Counting objects: 7, done.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 470 bytes, done.
Total 4 (delta 1), reused 0 (delta 0)
To [email protected]:project.git
64192f9..ad4b530 master -> master
*wchar_support* ブランチで、Jerryはワイド文字列のstrchr関数を実装します。 テストの後、彼は変更をコミットして *wchar_support* ブランチにプッシュします。
[jerry@CentOS src]$ git branch
master
 *wchar_support
[jerry@CentOS src]$ git diff

上記のコマンドは、次の結果を生成します-

diff --git a/src/string_operations.c b/src/string_operations.c
index 01ff4e0..163a779 100644
--- a/src/string_operations.c
+++ b/src/string_operations.c
@@ -1,6 +1,16 @@
#include <stdio.h>
#include <wchar.h>
+wchar_t* my_wstrchr(wchar_t *ws, wchar_t wc)

{

   while (*ws)
   {

      if (*ws == wc)

      return ws;

      ++ws;

   }
   + return NULL;

}

size_t my_wstrlen(const wchar_t *s)
{
   const wchar_t *p = s;

確認後、彼は変更をコミットします。

[jerry@CentOS src]$ git status -s
M string_operations.c

[jerry@CentOS src]$ git add string_operations.c

[jerry@CentOS src]$ git commit -m 'Addded strchr function for wide character string'
[wchar_support 9d201a9] Addded strchr function for wide character string
1 files changed, 10 insertions(+), 0 deletions(-)

[jerry@CentOS src]$ git push origin wchar_support

上記のコマンドは、次の結果を生成します-

Counting objects: 7, done.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 516 bytes, done.
Total 4 (delta 1), reused 0 (delta 0)
To [email protected]:project.git
3789fe8..9d201a9 wchar_support -> wchar_support

タックルの競合

トムは自分のプライベートブランチでジェリーが何をしているかを見たいので、 wchar_support ブランチから最新の変更をプルしようとしますが、Gitは次のエラーメッセージで操作を中止します。

[tom@CentOS src]$ git pull origin wchar_support

上記のコマンドは、次の結果を生成します-

remote: Counting objects: 11, done.
63Git Tutorials
remote: Compressing objects: 100% (8/8), done.
remote: Total 8 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (8/8), done.
From git.server.com:project
* branch
wchar_support -> FETCH_HEAD
Auto-merging src/string_operations.c
CONFLICT (content): Merge conflict in src/string_operations.c
Automatic merge failed; fix conflicts and then commit the result.

競合を解決する

エラーメッセージから、src/string_operations.cに競合があることが明らかです。 彼はgit diffコマンドを実行して、詳細を表示します。

[tom@CentOS src]$ git diff

上記のコマンドは、次の結果を生成します-

diff --cc src/string_operations.c
index 52bec84,163a779..0000000
--- a/src/string_operations.c
+++ b/src/string_operations.c
@@@ -1,8 -1,17 +1,22 @@@
#include <stdio.h>
#include <wchar.h>
++<<<<<<< HEAD
+/*wide character strlen fucntion*/
+size_t my_wc_strlen(const wchar_t *s)
++=======
+ wchar_t *my_wstrchr(wchar_t *ws, wchar_t wc)

{


   while (*ws)
   {
      if (*ws == wc)

      return ws;

      ++ws;

   }
   + return NULL;

}

+ size_t my_wstrlen(const wchar_t *s)
++>>>>>>>9d201a9c61bc4713f4095175f8954b642dae8f86
{
   const wchar_t *p = s;

トムとジェリーの両方が同じ関数の名前を変更したため、Gitは混乱の状態にあり、ユーザーに競合を手動で解決するように求めています。

トムはジェリーが提案した関数名を保持することにしましたが、彼はコメントをそのまま追加しました。 競合マーカーを削除すると、git diffは次のようになります。

[tom@CentOS src]$ git diff

上記のコマンドは、次の結果を生成します。

diff --cc src/string_operations.c
diff --cc src/string_operations.c
index 52bec84,163a779..0000000
--- a/src/string_operations.c
+++ b/src/string_operations.c
@@@ -1,8 -1,17 +1,18 @@@
#include <stdio.h>
#include <wchar.h>
+ wchar_t *my_wstrchr(wchar_t *ws, wchar_t wc)

{

   while (*ws)
   {

      if (*ws == wc)

      return ws;

      ++ws;

   }
   + return NULL;

}

+/*wide character strlen fucntion*/
- size_t my_wc_strlen(const wchar_t *s)
+ size_t my_wstrlen(const wchar_t *s)
{
   const wchar_t *p = s;

トムはファイルを変更したため、最初にこれらの変更をコミットする必要があり、その後、変更をプルできます。

[tom@CentOS src]$ git commit -a -m 'Resolved conflict'
[master 6b1ac36] Resolved conflict

[tom@CentOS src]$ git pull origin wchar_support.

トムは競合を解決し、プル操作が成功するようになりました。

Git-さまざまなプラットフォーム

GNU/LinuxおよびMac OSは* line-feed(LF)または改行を行末文字として使用しますが、Windowsは line-feedとキャリッジリターン(LFCR)*の組み合わせを使用して行末文字を表します。

これらの行末の違いによる不必要なコミットを回避するには、Gitリポジトリに同じ行末を書き込むようにGitクライアントを構成する必要があります。

Windowsシステムでは、チェックアウト中に行末を CRLF 形式に変換し、コミット操作中に LF 形式に戻すようにGitクライアントを構成できます。 次の設定で必要なことができます。

[tom@CentOS project]$ git config --global core.autocrlf true

GNU/LinuxまたはMac OSの場合、チェックアウト操作の実行中に行末を CRLF から LF に変換するようにGitクライアントを構成できます。

[tom@CentOS project]$ git config --global core.autocrlf input

Git-online-repositories