Git 基本命令

本文按照 设置工程分支与合并本地操作分享和更新 四步来简单说一下 Git 基本命令的用法。

注:git 命令如此之丰富,可以说,不论你有什么需求,遇到些什么问题,通过查命令都可以解决。如果命令一时看不懂,则 Google 一下或者直接上 stackoverflow,别人的做法会给你启发。

一句话,有问题不是事儿。不但不是事儿,反而是 get 新技能的契机。

命令帮助

每个命令的 Examples 部分是一个很好的学习命令使用的示例。

使用 git 命令行?还是 GUI 工具?

命令行对 git 所有命令都适用,也最安全,不容易出问题;而图形界面工具则不一定了,不过常用命令没什么大问题。

设置运行环境

git config --global user.name "your name" ; 设置你的称呼
git config --global user.email "your_email@example.com" ;设置你的邮箱;
git config --global push.default simple ;This is the safest option and is suited for beginners. 在 git push 时不必指定 [<repository> [<refspec>...]]
git config --global core.quotepath false ;解决 Windows Git Bash、Linux 下的中文转码问题;
git config --global core.editor /usr/bin/vim ;OS X 下 merge 命令 vi error 问题;通常 core.editor=vim。
git config --global core.autocrlf true ;Win Git Bash 时设置,见 git replacing LF with CRLF
git config --unset ;清除设置项。
git config --global credential.helper wincred ;Win Git Bash 启用 http/https 协议时设置。
git config -l ;查看所有的(name.key)/(value) -l | --list

设置工程(Clone repositories)
  • git clone ; 从远程复制资源库到本地库。
    git clone <repository> [<directory>]
    1. repository:远程库地址;
    2. directory:本地目录名;不指定,则默认为远程库名。如果目录已存在则必须是一个空目录;
# ssh:// URL 形式,看起来和 https URL 形式相似。ssh 需要的私钥文件在 ~/.ssh/config 文件中由 IdentityFile 参数指定。
git clone ssh://user@gitserver/path/to/project.git 
# 示例:git clone ssh://192.168.99.236/home/git/wanpinghui/wphdoc.git
# scp-like 语法
git clone user@gitserver:/path/to/project.git 
# 示例:git clone 192.168.99.236:/home/git/wanpinghui/wphdoc.git
服务器的 git 库约定以 .git 结尾,clone 后的工作区中的 git 库则不包含 .git。
  • 设置 .gitignore 文件
    在该文件中,设置 commit 时要忽略的文件匹配模式,避免提交一些临时文件到库里。
# 在工程根目录下建一个文件 .gitignore,是一个受控文件。以下为文件内容示例。
# 忽略 PHP 临时工作文件
.buildpath
.project
.settings/
# 忽略 Mac 临时工作文件
.DS_Store
  • build和lib 实际上是空文件夹,保留.gitkeep仅为在 git 上受控。
# cat .gitignore
build/*
!build/.gitkeep
lib/*
!lib/.gitkeep

git ls-files -o -i -X .gitignore 仅查看 ignored 的文件,匹配模式从 .gitignore 文件中获取(--others,--ignored,--exclude-from)。了解 git ls-files
git status --ignored 也会列出 ignored 的文件;了解 git status
git ls-files -o --directory 可以查看非受控文件和目录列表(--others)。

分支与合并(Create branches)
  • git branch ; 看本地当前分支( local branches)情况,以及当前工作区位于哪个分支。
    git branch -r 看远程跟踪分支(remote-tracking branches)情况,--remotes。
    git branch -d <branch>;删除 <branch>,--delete;
    git branch -a ;查看本地和远程所有分支情况,--all;
    git branch -m <new-branch-name>:修改当前分支名,详见 How To Change Branch Name on Git

  • git checkout <branch> ;将工作区切换到分支,这有点类似于 svn checkout。master 也是一个分支。
    示例:git checkout v0.1 ; v0.1 表示分支名称。

  • git branch <new_branch> [<start-point>]; 在本地开分支。注意:仅仅开分支,并不自动将工作区切换到分支;[<start-point>] 表示从哪里开始分支,默认指向当前 HEAD;
    git branch v0.7e v0.7d,表示 从 v0.7d 开一个新分支 v0.7e;

  • git checkout -b <new_branch> [<start-point>];开后即刻签出;

  • git merge(合并)
    Join two or more development histories together。

  • git reset --merge: 在 git merge iwifi 合并分支操作后,你发现有问题,则执行此句可立马恢复所做的合并。

  • git reset 恢复
    git reset [<commit>] 在没有 push 前将本地库恢复到指定 <commit>。

  • git log --name-status --oneline 常用命令

    可以查看变化的文件列表

  • git log --pretty=oneline|medium
    列出 commit 全值,以便类似于 svn 取出指定 revision,甚至某一个文件:git checkout <commit> [path/file]。

  • git log --patch

  • git log --stat (列出简略的统计数据:abbreviated stats for each commit)

  • git shortlog

在工作区和本地库操作(Basic Snapshotting | Commit changes)
  • git add ; 新文件或者本地修改了的文件,都需要 add。
  • git status
    git status -s ; Short Status
  • git commit
    git commit -m '注释':--message
    git commit -uno:不要列出 untracked-files
    git commit -a -m '注释';-a | --all 表示包含所有 modified and deleted files,但新文件需提前 git add。相比添加文件,修改文件是个更常见动作,加 -a 参数即可省略 git add。
分享和更新(Share code)

将你的修改分享出去到远程库和从远程库更新到本地库。

  • git fetch(下载)
    Download objects and refs from another repository 从远程主机将变更下载到本地,但不进行合并。
  • git push --set-upstream origin v0.1 ; set upstream for git pull/status, [-u | --set-upstream].
    Pushing to Your Remotes 将你本地的变更推送到远程主机。多人协同开发,请及时 push。
  • git pull [<repository> [<refspec>...]] (常用)
    Fetch from and integrate with another repository or a local branch 从远程主机将变更取到本地库,同时进行合并。pull 实际是把 fetch 和 merge 两个命令的操作放到一个命令里了。使用 pull 通常没有太大问题。不过仍然建议分开使用 fetch and merge。
    示例:git pull origin v0.1 ; 从远程 origin 的分支 v0.1 更新到本地库
  • git remote -v

$ git remote --verbose
origin git@192.168.1.91:/path/to/wphdoc.git (fetch)
origin git@192.168.1.91:/path/to/wphdoc.git (push)

  • 远程地址变化
    git remote set-url origin <新地址> 或者remove+add。
git tag
  • 打 Tag 是很容易的,tag 其实就是一个 commit 的别名;自然删除 tag 也是极容易的;
  • 打 Tag:git tag -m <tag name> [<commit>]
    • 其中 -m <msg> 表示 tag 备注,每个tag都必须给出说明。多个 -m 就是多个段落,对 tag 可以有了更详细的描述。
  • 推送到远程:git push <remote> <tag name>
  • 对于 GitHub 来说,打了一个 Tag 就有了一个 Release;
  • 在 GitHub 上通过自定义脚本,可以同步更新 Packagist 上的 composer 包;
  • GitHub 上的 Release 的命名有类似 v1.8的,也有 1.8,1.8-rc1 的;
文件对比 git diff

在开发中,经常会修改文件,提交时或者 review 时也就经常需要对比文件:

  • 工作区和库中比对
  • 在不同 commit 间比对
  • 在不同 branch 间比对(branch 也是一个 commit,故也是 commit 比对)
  • git diff --name-only # 列出有变化的文件;
    How to list only the file names that changed between two commits?
  • vim -p git diff --name-only
    vim 编辑所有有变化的文件,编辑时,一个文件一个tab。
  • git diff HEAD
    See the difference between your current files and your last commit.
  • git diff --staged
    See the difference between your staged files and your last commit.
  • git stash
    Temporarily store changes in a "dirty" working directory.

使用 git diff 进行比对的可视化程度比较低,不论 markdown(md) 文档还是 code,都差强人意。相反 git difftool 却值得推荐。

使用 git difftool

使用第三方的 difftool 来进行比对,我们选用 vimdiff 这个比对工具。vimdiff 一般就是一个 vim 的 link。也就是说 vim 编辑器本身是支持进行文件比对的。vim 是一个程序员绝对要熟悉的工具。

git config --global diff.tool vimdiff
git config --global merge.tool vimdiff
git config --global difftool.prompt false

difftool.prompt 关闭提示是必要的。你在执行 git difftool 命令时,如果有多个待比对文件,则每次 vim 启动比对时都询问,你会感到不爽的。关闭提示最好。当然 git difftool --no-prompt 也可以。

git difftool .
git difftool <specific file>
git difftool <commit> [<commit>] [path]
git difftool HEAD^ # HEAD 和其前一次 commit 比对,即查看最新一次提交的修改记录;
  • 比对时,查看不同点的快捷键
    [c 上一个不同点
    ]c 下一个不同点
关于导出代码
  • git checkout-index
  • Do a “git export” (like “svn export”)?
    直接导出纯代码,不包含 .git 等历史记录和控制信息。
    git checkout-index -a -f --prefix=/destination/path/
    注意:path 后面必须有/,作为最后一级目录,path 必须未创建。如果 path 已经创建或者path后面没有/,就会签出到 /destination/目录下,签出的文件和目录以 path 作为前缀。
关于 checkout 的 examples(放弃修改,重新签出文件)

The following sequence checks out the master branch, reverts the Makefile to two revisions back, deletes hello.c by mistake, and gets it back from the index.

$ git checkout master                   **(1)**
$ git checkout master~2 Makefile        **(2)**
$ rm -f hello.c
$ git checkout hello.c                  **(3)**

(1) switch branch
(2) take a file out of another commit
(3) restore hello.c from the index

  • 签出某一个 branch 或者 commit 下的 某个文件
    git checkout <branch|commit> [path/file]

  • 工作区的修改(放弃修改)
    git checkout <filename>:放弃指定文件;
    git checkout .:放弃所有修改;
    git checkout -- .:放弃当前目录及其子目录下的修改;

  • 本地库的修改
    如果文件已经提交,但尚未 push 到远程,则 git reset <commit> 即可(这个commit 之后所做的修改都保留在工作区,即默认 --soft。回滚到上次就是 git reset HEAD^),git reset --hard <commit> 则直接放弃所做修改(慎重)。

问题:Git cannot add a completely empty directory

Git 不支持加一个空目录,原因是 Git 处理的是文件,Git 不把目录作为对象进行处理。建议你在空目录下加一个 .gitignore 文件,提交上去即可,那个目录看起来是一个空目录。

# Ignore everything in this directory
*
# Except this file
!.gitignore
  1. How can I add an empty directory to a Git repository?
  2. Commit empty folder structure (with git)

注:如果你连 .gitignore 也不想加,通过 touch README.md 加一个零字节空文件也不是不行。

使用 git fetch 查看远程库有否修改

有时候,你仅仅想 查看一下远程库有否修改,而不想对本地做任何更改,使用 git fetch 即可。

$ git status
On branch v0.3
Your branch is up-to-date with 'origin/v0.3'.
nothing to commit, working directory clean

从以上 git status 的输出可以看到,本地没有变更。下面看一下 git fetch 的输出:

$ git fetch --dry-run --verbose
POST git-upload-pack (957 bytes)
remote: Counting objects: 1194, done.
remote: Compressing objects: 100% (12/12), done.
remote: Total 1194 (delta 13), reused 12 (delta 12), pack-reused 1170
Receiving objects: 100% (1194/1194), 9.05 MiB | 740.00 KiB/s, done.
Resolving deltas: 100% (751/751), completed with 7 local objects.
From https://github.com/w..p...h../web
   cc796ed..19cc48e  v0.3       -> origin/v0.3
 = [up to date]      master     -> origin/master

以上 git fetch 的输出可以看到,本地 v0.3 缺少从 cc796ed 直到 19cc48e 的 commits,即远程库有修改。

使用 git fetch 下载,可以查看每次 commit 的修改记录
$ git fetch origin v0.3
From https://github.com/w..p...h../web
 * branch            v0.3       -> FETCH_HEAD
   cc796ed..19cc48e  v0.3       -> origin/v0.3

$ git status
On branch v0.3
Your branch is behind 'origin/v0.3' by 133 commits, and can be fast-forwarded.
  (use "git pull" to update your local branch)
nothing to commit, working directory clean

$ git log FETCH_HEAD
(略) 你就能看到远程库所做的修改;

请区别 HEAD | origin/HEAD | origin/master:

  • git reset --hard HEAD
  • git reset --hard origin/HEAD
  • git reset --hard origin/master
关于 git log

Viewing the Commit History 了解 git log 比较容易。

  • --decorate: Print out the ref names of any commits that are shown.
  • --all: Pretend as if all the refs in refs/ are listed on the command line as <commit>.
  • git log --pretty=oneline --decorate --all -3
7055c613f081be5bd063d4695bbd2f9e593039bd (origin/v0.3, origin/HEAD) 修改个人信息页
5e8668d78c92875d9efc5707f5fadb4a071f9b36 (HEAD -> v0.3) 为了迁就压缩,js统统放到dists目录下
f2882da667ba6d3a83edd331c8e51317b053f9b5 @@include参数必须用双引号,单引号发布失败
HEAD -> v0.3 图示
  • git log --name-status --oneline --decorate --graph --all
    查看所有分支情况,简单、清晰图形标识分支;
  • git log --name-status -n 5 --pretty=format:"%an %ad %s"
    列出发生变更的文件的名字及其状态,限于 5 个 commits,格式:author name, author date, subject。这个和 svn 格式比较贴近。通过 git config --global format.pretty "%an %ad %s" 设置格式。
如何搜索查看已删除文件?

有时我们删除了一个文件,但又记不起在哪个 commit 删除的,怎么办

  • git log --all **/<filename>
    git log --all --name-status **/*<partoffilename>*
    --name-status 列出文件目录,**/ 表示任意路径;
  • Get a list of the deleted files and copy the full path of the deleted file.
    git log --diff-filter=D --summary | grep delete

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容

  • git常用命令 GIT常用命令备忘:http://stormzhang.com/git/2014/01/27/gi...
    新篇章阅读 8,449评论 1 26
  • 本文作者陈云峰,转载请注明。 这篇文章记录个人常用的一些命令,和记不住的一些命令,转载了并不断更新。 Git官网 ...
    陳云峰阅读 2,803评论 0 24
  • 今天孩子早早起床的第一件事就是读拼音,她说今天老师要检查的,看来孩子对学习的态度还是好的,武校长说过,一年级的孩子...
    雅琳妈妈阅读 170评论 0 0
  • 男朋友放我飞机,然后怎么调节心情呢? 本来安排好的元旦过去找他,结果,他又有事情陪不了我,刚好元旦是例假期,我跑来...
    郭云阅读 106评论 2 1
  • 很多公司都要求班组或者团队,在开始工作前召开班组会或者班前会,有的人对此不理解,觉得没有必要,或者坚持了一段...
    认真断舍离阅读 1,798评论 0 0