Git 基本操作

Posted Wallace JW

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Git 基本操作相关的知识,希望对你有一定的参考价值。

基本流程

git 的基本工作流程如下

  1. 使用某种 git hosting tool(如 github,bitbucket)创建项目代码仓库(repository)。
  2. 将远端代码仓库克隆(clone)或者拉取(pull)到本地工作区。
  3. 创建开发分支(branch),在本地分支对文件进行编辑操作,并将文件从工作区添加 (add) 到暂存区(stage)
  4. 将文件从暂存区提交(commit)到版本库
  5. 将本地版本库的内容推送 (push) 到远端版本库
  6. 创建 pull request,将开发分支合并到主分支(master)

关于工作区,暂存区和版本库的概念可以参考 菜鸟教程

本地版本库

Create Repository

创建一个新的文件夹路径,在该路径下执行 git init

$ git init
# output: Initialized empty Git repository in ...

创建了一个空的版本库(empty Git Repository)

将文件提交给 Repository

在要添加的文件放在工作区路径下,用 git add 命令添加到版本库中,实际上是将修改添加到暂存区 stage。然后用 git commit 命令提交到版本库,实际上是将暂存区的所有内容提交到分支 branch。如新建一个 readme.txt 文件

$ git add readme.txt
$ git commit -m "wrote a readme file"  # -m 后面的为提交的说明
# output : 显示有多少个文件被修改,插入了几行内容,如:
# 1 file changed, 2 insertions(+)
# create mode 100644 readme.txt

commit可以一次提交很多文件,所以可以多次add不同的文件,在一起提交

也可以一次 add 所有变动的文件,具体参数如下:

查看 Repository 状态

$ git status

如果没有待提交的修改内容,显示:

On branch master
nothing to commit, working tree clean

可以用 git diff 查看版本库里文件的变化情况,如修改 readme.txt

$ git diff readme.txt

版本回滚

使用 git log 查看提交日志

$ git log    # 完整信息
$ git log --pretty=oneline  # 简洁信息

可以看到所有提交记录,其中 HEAD 为当前版本,上一个版本就是HEAD^,上上一个版本就是HEAD^^,往上一百个版本写作HEAD~100。使用 git reset 命令回退到指定的版本。

$ git reset --hard HEAD^
# output : HEAD is now at f7a2047 wrote a readme file

修改后再使用 git log,发现原来的 HEAD 版本已经消失了,上一个版本变成了 HEAD,查看本地的 readme.txt,变回了上一个版本的内容。

如果想要撤销这次回滚,需要找到原来 HEAD 的 commit ID。Git提供了命令git reflog用来记录你的每一次命令。

$ git reflog
f7a2047 (HEAD -> master) HEAD@0: reset: moving to HEAD^
e820964 HEAD@1: checkout: moving from master to master
e820964 HEAD@2: commit: edit readme
f7a2047 (HEAD -> master) HEAD@3: checkout: moving from master to master
f7a2047 (HEAD -> master) HEAD@4: commit (initial): wrote a readme file

可以看到 edit readme 那一个版本的 commit id 为 e820964

$ git reset --hard e820964
# output : HEAD is now at e820964 edit readme

使用 git reset,即可撤销回滚。

丢弃修改

使用 git reset HEAD 把暂存区的修改撤销掉(unstage),使用 git checkout 丢弃工作区的修改

$ git reset HEAD readme.txt
$ git checkout -- readme.txt

删除文件

在本地工作区把文件删除,然后用 git status 查看,可以看到 deleted 的修改

$ rm license.txt

如果要从版本库中也删除,使用 git rm,并 git commit

$ git rm license.txt
$ git commit -m "remove license.txt"

否则,如果是本地删错了,可以用 git checkout 恢复

$ git checkout -- license.txt

远程版本库

创建远程版本库

创建 SSH Key

$ ssh-keygen -t rsa -C "youremail@example.com"

在用户主目录里找到.ssh目录,里面有id_rsaid_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。

在 Github 或者 Bitbucket 等网站维护 SSH Key

本地版本库推送到远程

本文均使用 Bitbucket

$ git remote add origin git@bitbucket.org:账户名/本地仓库.git
$ git push -u origin master   # 第一次使用的时候要加 -u

将本地分支推送到远端

每次本地修改的内容提交到本地分支后,即可推送到远端

$ git push origin master

远程版本库克隆到本地

$ git_test klook$ git clone git@bitbucket.org:用户名/远端仓库.git

分支管理

分支详解

在实际开发中,我们应该按照几个基本原则进行分支管理:

  • master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面工作
  • 平时工作都在dev分支上,到版本发布时,再把dev分支合并到master上,在master分支发布新版本

创建与合并分支

首先,我们创建dev分支,然后切换到dev分支:

$ git checkout -b dev
Switched to a new branch 'dev'

git checkout命令加上-b参数表示创建并切换,相当于以下两条命令:

$ git branch dev            # 创建
$ git checkout dev					# 切换
Switched to branch 'dev'

然后,用git branch命令查看当前分支,git branch命令会列出所有分支,当前分支前面会标一个*号。

$ git branch
* dev
  master

然后,我们就可以在dev分支上正常提交,提交完成后,切换回 master 分支,发现在 dev 上的修改不见了。

接下来把 dev 分支合并到 master 上

$ git merge dev

再次查看,发现修改生效了。

合并完成后,就可以删除 dev 分支了。

$ git branch -d dev
Deleted branch dev (was b17d20e).
# 注意:如果要丢弃一个没有合并过的分支,要用大写 -D
# git branch -D dev

注意:常规情况下合并分支时会使用 Fast forward,这种方式非常快,但是删除分支后,会丢失分支合并记录,如果希望在分支历史中可以看出分支信息,需要禁用 fast forward。

$ git merge --no-ff -m "merge with no-ff" dev

从远程拉取分支

从远程拉取分支,使用git pull,如果有冲突,要先处理冲突。

$ git pull

分支冲突

如果在不同分支分别对同一段代码做了修改,合并的时候就可能会产生冲突,无法合并。

$ git merge dev
Auto-merging readme.txt
CONFLICT (content): Merge conflict in readme.txt
Automatic merge failed; fix conflicts and then commit the result.

使用 git status 查看冲突的来源

$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)

	both modified:   readme.txt
	
no changes added to commit (use "git add" and/or "git commit -a")

此时查看 readme.txt,会发现 Git用<<<<<<<=======>>>>>>>标记出不同分支的内容,需要手动修改。

Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes of files.
<<<<<<< HEAD
Creating a new branch is quick & simple.
=======
Creating a new branch is quick AND simple.
>>>>>>> dev

手动修改完后保存,重新提交,可以提交成功

$ git add readme.txt 
$ git commit -m "conflict fixed"
[master cf810e4] conflict fixed

可以使用 git log 查看分支合并情况

$ git log --graph --pretty=oneline --abbrev-commit
*   f2e26fd (HEAD -> master) fixed conflict
|\\  
| * ea21f03 (dev) edit in dev
* | 4db5175 edit in master
|/  
* 08391f4 (origin/master, origin/dev) branch test
* 05db268 edit func
* b9ee14c add user_api.go
* 9892edc remove license.txt
* 37d014f add license and modify readme
* e820964 edit readme
* f7a2047 wrote a readme file

最后删除 dev 分支,工作完成。

删除分支

删除本地分支

git branch -d <BranchName>

删除远程分支

git push origin --delete <BranchName>

删除某一次提交(或者某一次 merge)

step 1: 查询日志找到想要恢复到的那一次提交

比如最新一次提交是 a, 倒数第二次提交是 b, 想要恢复到 b,找出 b 的 commit id

git log

step 2: reset 到要恢复的版本

git reset (b 的 commit id)

step 3: 修改内容

step 4: 正常 push 会因为落后远端分支而失败,需要强制推送

git push -f 分支名

其他

查看远程库信息,使用git remote -v

本地新建的分支如果不推送到远程,对其他人就是不可见的;

从本地推送分支,使用git push origin branch-name,如果推送失败,先用git pull抓取远程的新提交;

在本地创建和远程分支对应的分支,使用git checkout -b branch-name origin/branch-name,本地和远程分支的名称最好一致;

建立本地分支和远程分支的关联,使用git push -u origin branch-name

标签

往当前的 commit 打标签,使用 git tag 命令

$ git tag v1.0

往之前的 commit 打标签,需要先找到历史提交的 commit id

$ git log --pretty=oneline --abbrev-commit

然后对指定的 commit id 打标签,如:

$ git tag v0.9 ea21f03

使用命令 git tag 可以查看标签

可以查看固定标签的内容

$ git show v1.0

注意:标签总是和某个commit挂钩。如果这个commit既出现在master分支,又出现在dev分支,那么在这两个分支上都可以看到这个标签。

标签也可以删除

$ git tag -d v1.0

命令git push origin可以推送一个本地标签;

命令git push origin --tags可以推送全部未推送过的本地标签;

命令git push origin :refs/tags/可以删除一个远程标签。

以上是关于Git 基本操作的主要内容,如果未能解决你的问题,请参考以下文章

Git 分支管理

vscode-git中的U,M和D文件标记含义

git clone 指定分支操作

git提交的具体操作

Git - 08. git branch

Git 撤消操作