本文主要记录一些工作中常用的 git 命令,以及一些比较特殊的git用法,希望这些命令对您也能有所帮助。
git 的基本工作原理
其实要想使用好git,你必须要知道一点git的工作原理,否则你在使用git时就只能死记硬背一些命令。如果你还处理死记硬背一些git命令的阶段,那么一旦你遇到一个非常复杂的或非手棘手的git case时,可以100%肯定你是无法解决的。
因此,了解一点git的基本工作原理是我们每个开发人员都必须的基础知识,下面我就对git的的基本工作原理做一下简要介绍。
git的结构
首先我们必须要清楚是,git是由三大部分组成的,即本地工作区,本地仓库以及远程仓库。
- 本地工作区,就是你平常写代码或修改代码的地方。
- 本地仓库,就是我们工作区中.git目录。它里边有一堆子目录,这些子目录都有各自的用途,我们暂且不管。
- 远程仓库,这个比较好理解了,就是远端的git仓库,比如我们在github上创建的仓库。
通过下面这张图我们可以更直观的了解这三大部分:
从图中我们可以清楚的知道,平时我们使用git的三个主要命令(git add、git commit、git push)具体都做了些什么:
- git add: 将本地工作区中代码的修改保存到本地仓库的staged区,即暂存区。
- git commit: 将staged区中的内容保存到本地仓库。
- git push: 将本地仓库中的内容推送给远程仓库保存。
通过上面这张图我们可以得出以下几点重要结论。
第一,git在处理我们的提交时是按顺序、分阶段的。比如我们的一个提交,必须先到 staged 后才能进入本地仓库,这个处理顺序是不能乱的。
第二,git管理中有一个 HEAD 指针,它始终指向正在处理的git commit。而它的前一次git commit 可以用HEAD^
表式,它的上上次commit可以用HEAD ^^
表式。
第三,当我们想用地本仓库的内容更新本地工作区的内容时,如果 staged 中没有内容,则可以直接用本地仓库的内容更新本地工作区内容。但如果 staged 中有内容,则需要先更新staged ,然后再更新本地工作区。
第四,git的核心是本地仓库,所有的操作都是围绕着它来的。它既是用户commit
的终点,又是远程仓库的接收commit
起点。我们在使用git时,可以向本地仓库提交多次修改,而只向远程仓库推送一次,git推送时会将之前的多个commit
合并到一起。
git的分支管理
在git中还有一个特别重要的概念就是branch,即分支。它是我们多人合作开发的基础。如下图所示:
通过上图我们可以清楚的知道,git是以指针的方式对分支进行管理的。下面我们来详述一下git是如何管理分支的。
当我们执行git init
时,git默认为我们创建一个分支,即Master
分支。而HEAD指针也被初始化指向Master分支,因此每当你提交新的修改时,这些修改都会被压入到Master分支栈上。
当然一般情况下我们都不会轻易对Master分支做操作,而是创建一个Dev
分支作为我们的开发分支。在git中你可以执行git branch branchname
命令来创建一个新分支,比如将branchname设置为Dev
,这样我们就创建出了Dev
分支。
然后你可以执行git checkout Dev
命令,它的作用是让HEAD
指向Dev分支。后面你所有的commit就都被push到Dev分支上了。
如果你觉得执行两条命令比较麻烦,你也可以将上面的两步合并为一步,执行git checkout -b branchname
这一条命令就可以了,这也是我们平常真正使用的命令。
通过上面的描述,我想你应该对git的工作原理有了最基本的了解了,下面我们再来看这些命令时就很容易理解它们的作用以及为什么要这么做了。
已有代码该如何提效到仓库中
第一步,在github 上创建一个仓库。
第二步,执行下面的代码
1 | git remote add origin git@github.com:avdance/test.git |
本地与远程有突冲,想放弃本地修改
1 | git reset --hard FETCH_HEAD |
重新从远端拉取某个文件
1 | git checkout -- a.c |
撤消某次 add
1 | git rm --cached <added_file_to_undo> |
撤消某次 commit
1 | git reset --soft commitID 只是删除了commitId之后的commit记录,但是代码改动仍然存在 |
将本地修改先暂存起来
1 | git stash 将本地修改暂存起来 |
查看有冲突的文件
1 | git status -uno |
不显示临时文件
在 .gitignore 中添加不想被 git staus 看到的文件或目录
暂时回滚到某版本
首先通过 git log查看你之前的提交码
1 | git log | more |
commit 4adb3f0ecd9dbc79bd09666d88f8c2520305c001
Author: xxxxxx
Date: Thu Jan 25 11:51:45 2018 +0800
摘取 commit 码的前 7位,执行下面的命令
1 | git checkout 4adb3f0 |
切换/回滚到主分支
1 | git checkout master |
服务端有更新,但你却 commit了你的代码
- 先拉取服务端代码
1
git pull
- 提交代码
1
git push
- 如果你在 dev分支,此时还要拉取master的代码
1. 先 切换到 master 分支2. 拉取代码1
git checkout master
3. 重新切换到 dev 分支1
git pull
1
git checkout dev
查看每次提交的文件列表
1 | git log --stat | more |
查看某些提交代码的变化
1 | git show <commit id> [<filename>] |
显示所有本地与远端分支
1 | git branch -a |
显示所有远程分支
1 | git branch -r |
显示远端地址
1 | git remote -v |
创建一个新分支
1 | git checkout -b new_branch |
或
1 | git checkout -b new_branch refs/remotes/branch-heads/branch |
删除本地分支
1 | git branch -d branch |
查找与某个commitID 相关的branch
1 | git branch --contains commitID --all |
删除远端分支
1 | git push origin --delete remotebranch |
远程仓库已经删除,而本地仓库还在,如果清除?
1 | git pull -p |
git diff 不显示修改的内容
有些情况下,通过 git status
能查到某些文件有变化,但使用 git diff
却看不到修改的内容。可以使用下面的面试查看变化。
- 第一种方法
1
git diff --cached 文件名
- 或者
先将修改的文件重命名,然后执行下面的语句1
git reset HEAD
配置更好的 git diff 工具
在使用 git diff 时,常常发现有很多不方便的地方。因为git diff 默认使用 patch 方式展示代码的不同。如果想看修改后代码的上下文就比较麻烦了(比如代码 review)。
其实 git 已经提供了扩展功能。可经将它的默认 diff 工具修改为vimdiff。配置如下:
- 首先打开 git config 文件
1
vim ~/.gitconfig
- 增加配置项
1
2
3
4
5
6
7[difftool]
prompt = false
[diff]
vimdiff
tool = vimdiff
[difftool "vimdiff"]
path = /usr/bin/vimdiff
打tag
1 | //为git打tag, 第一次需要在前面加一个v |
git merge 每次都生成一次commit
1 | git merge --no-ff |
注:ff表示 fast forward
切到某个tag
与切到某个分支是类似的,只不过将branch 名换为 tag 名而以。
1 | git checkout tag_name |
查看某个人的所有提交
1 | git log --author=“author” |
为git设置默认用户名和密码
在使用Git 的时候,经常会遇到需要频繁输入密码的情况,每次git push 和 git pull 都要求输入用户名和密码,如果提交频繁的话就十分不方便。
可以使用下面的方法,只需要第一次输入用户名和密码,以后都不用再输入了。
进入Git 配置文件
1 | vim ~/.gitconfig |
修改配置文件,添加下面这一行。
1 | [credential] |
修改已提交的commit的用户名邮箱
第一步
1
2git config --global user.name "newName"
git config --global user.email "newEmail"修改已提交commit的用户名邮箱
1
git commit --amend --author="userName <userEmail>"
注意不能缺少< >
此指令仅能更新最近的一次commit的用户名邮箱
git 应用 patch
- 预览patch的结是
1 | git apply --stat file.patch |
- 检测patch后是否有错误
1 | git apply --check file.patch |
- 打patch
1 | git am --signoff < a_file.patch |
- 执行commit
1 | git commit -m "" |
- 提交代码
1 | git push |
循环克隆
1 | git clone --recursive https://xxx.git |
给代码设置两个不同的源
1 | git remote set-url origin https://xxx.git |
结束语
命令在不断更新中…