ご存知のとおり、Git は現在、分散バージョン管理の分野のリーダーであり、Git を中心に完全なエコシステムが形成されています。 Git を学習するには、まず Git の基本的なワークフローを学習します。 SVN などの従来のバージョン管理システムと比較して、Git は分散バージョン管理用に設計された強力なツールです。 Git を使用するときによく使用されるコマンドには、pull、commit、push などがあり、非常に簡単そうに見えます。ただし、マージ競合が発生する場合は、Git によって競合がマークされ、手動で解決する必要がある場合があります。場合によっては、誤ってコードを間違ったブランチにコミットし、リモート リポジトリにプッシュしてしまうことがあります。別のブランチに切り替える必要がある場合でも、未保存の変更が残っているために Git ではそれができない場合もあります。別のブランチからのコミットを通じてコードにパッチを適用する必要がある場合はどうすればよいでしょうか?この記事では、これらのコマンドを適切に使用すると、Git の適用効率が大幅に向上する 12 の高度な Git コマンドを紹介します。
1. アップストリームの変更をプルするには、マージの代わりにリベースを使用します
ブランチのマージはマージコミットとして記録されますが、これは理にかなっています。たとえば、これは、新しい機能がリリース ブランチにマージされたことを示すために使用できます。ただし、複数のチーム メンバーがプロジェクトで作業し、通常の git pull を使用してブランチを同期すると、コミット タイムラインが不要なマージ コミットで汚染されてしまいます。より良いアプローチは、git rebase を使用してフィーチャー ブランチをマスター ブランチにリベースすることです:
$ git checkout feature $ git rebase master
そうすると、フィーチャー ブランチ全体がマスター ブランチの開始点に移動され、マスター ブランチ上のすべての新しいコミットがマージされます。ただし、マージ コミットを使用する場合と比較して、リベースでは元のブランチのコミットごとに新しいコミットを作成することでプロジェクト履歴が書き換えられます。リベースの主な利点は、よりクリーンなプロジェクト履歴が得られることです。さらに、ここではリベースの落とし穴についていくつか説明します。
2. git rebase 実行後にマージ競合を解決する
より大きな能力にはより大きな責任が伴います。 git rebase を実行すると、マージ競合が発生する可能性があります。マージの競合とは、2 つのコミットが同じファイルの同じ行を変更し、Git がどの変更を適用すればよいのかわからないことを意味します。これにより、次のようなエラー メッセージが表示されます:
Git では、競合 (fa39187) の原因となったコミットを修正するための 3 つのオプションが提供されます:
git rebase --abort を実行すると、リベースを完全にキャンセルできます。これを行うと、リベースの変更がキャンセルされ、ブランチが git rebase を実行する前の状態に戻ります。
git rebase --skip を実行すると、コミットを完全に無視できます。こうすることで、問題のコミットによって導入された変更は履歴に追加されません。
競合は、マージ競合と同じ標準手順を使用して解決できます。
3. 変更を一時的に保存します
作業を進めていると、何かと雑な状態になることがよくあります。現時点で別のブランチに切り替える必要がある場合はどうすればよいですか?まだ保存されていない変更があるため、Git ではこれを行うことはできません。率直に言って、中途半端な完成品を提出して、後で修正することは望ましくありません。この問題の解決策は、git stash コマンドを使用することです。 Stash は、作業ディレクトリの現在のステータス (たとえば、変更された追跡ファイルやステージング領域への変更など) を受信し、それを未完了の変更スタックに保存して、後でいつでも変更できるようにします。次のコマンドを使用して作業をステージングできます:
$ git stash
保存された作業ディレクトリとインデックスの状態 WIP on feature: 3fc175f fixracecondition
HEAD is now at 3fc175f fixracecondition
これで、作業ディレクトリはクリーンになりました現在:
$ git status # On branch feature nothing to commit, working directory clean
現時点では、ブランチを安全に切り替えて他のことを行うことができます。ただし、心配しないでください。ステージングされたコミットはまだそこにあります:
$ git stash list stash@{0}: WIP on feature: 3fc175f fix race condition
その後、機能ブランチに戻った後、ステージングされたすべての変更を取得できます:
$ git stash pop On branch feature Changes not staged for commit: (use "git add ..." to update what will be committed) modified: index.html Dropped refs/stash@{0} (ac2321cc3a33ba712b8e50c99a99d3c20da9d6b8)
以下に示すように、ステージングに関しては、他にもいくつかのオプションが利用可能です。 :
$ git stash save "describe it" # give the stash a name $ git stash clear # delete a stashed commit $ git stash save --keep-index # stash only unstaged files
4. 特定のリモートブランチをクローンする
リモートリポジトリから特定のブランチをクローンしたい場合はどうすればよいでしょうか?通常は git clone を使用しますが、これを行うと他のすべてのブランチも同様に複製されます。便利な方法は git Remote add を使うことです:
$ git init $ git remote add -t-f origin$ git checkout
5. チェリーピックしたリモートコミットを自分のブランチにマージします
さらに、リモートウェアハウスの特定のコミットだけを自分のブランチにマージしたい場合はどうすればよいでしょうかやれ? git Cherry-pick を使用して、指定された SHA 値を持つコミットを選択し、現在のブランチにマージできます:
$ git cherry-pick
6. 無関係なローカル リポジトリからパッチを適用します
別の無関係なローカル リポジトリをマージする必要がある場合 適用方法ウェアハウスのパッチを現在のウェアハウスに送信しますか?答えは次のコマンドです:
$ git --git-dir=/.git format-patch -k -1 --stdout| git am -3 -k
7. 追跡ファイルの変更を無視します
如果你和你的同事操纵的是相同分支,那么很有可能需要频繁执行git merge或是git rebase。不过,这么做可能会重置一些与环境相关的配置文件,这样在每次合并后都需要修改。与之相反,你可以通过如下命令永久性地告诉Git不要管某个本地文件:
$ git update-index --assume-unchanged
8. 每隔X秒运行一次git pull
通常,合并冲突出现的原因在于你正在工作的本地仓库不再反映远程仓库的当前状态。这正是我们为什么每天早晨要首先执行一次git pull的缘故。此外,你还可以在后台通过脚本(或是使用GNU Screen)每隔X秒调用一次git pull:
$ screen $ for((i=1;i<=10000;i+=1)); do sleep X && git pull; done
9. 将子目录分隔为新的仓库
有时,你可能需要将Git仓库中某个特定的目录转换为一个全新的仓库。这可以通过git filter-branch来实现:
$ git filter-branch --prune-empty --subdirectory-filtermaster # Filter the master branch to your directory and remove empty commits Rewrite 48dc599c80e20527ed902928085e7861e6b3cbe6 (89/89) Ref 'refs/heads/master' was rewritten
现在,仓库会包含指定子目录中的所有文件。虽然之前的所有文件都会被删除,但他们依旧存在于Git历史中。现在可以将新的本地仓库推送到远程了。
10. 清理
有时,Git会提示“untracked working tree files”会“overwritten by checkout”。造成这种情况的原因有很多。不过通常来说,我们可以使用如下命令来保持工作树的整洁,从而防止这种情况的发生:
$ git clean -f # remove untracked files $ git clean -fd # remove untracked files/directories $ git clean -nfd # list all files/directories that would be removed
11. 将项目文件打成tar包,并且排除.git目录
有时,你需要将项目副本提供给无法访问GitHub仓库的外部成员。最简单的方式就是使用tar或zip来打包所有的项目文件。不过,如果不小心,隐藏的.git目录就会包含到tar文件中,这会导致文件体积变大;同时,如果里面的文件与接收者自己的Git仓库弄混了,那就更加令人头疼了。轻松的做法则是自动从tar文件中排除掉.git目录:
$ tar cJf.tar.xz/ --exclude-vcs
12. 查找修改者
最后,如果出现混乱的情况,你一定想要找出是谁造成的。如果生产服务器宕机,那么找到罪魁祸首是比较容易的事情:只需执行git blame。该命令会显示出文件中每一行的作者,提交hash则会找出该行的上一次修改,还能看到提交的时间戳:
$ git blame
当然,Git命令是非常多的,除了上面介绍的12个重要命令外,相信各位InfoQ读者在日常工作过程中也有自己偏爱且好用的一些命令,不妨以评论的形式与其他读者一同分享。