git常用命令

安装git

linux系统安装

sudo yum install git

如果是基于Debian的发行版,即Ubuntu系统

sudo apt-get install git

mac系统安装

mac一般自带git

如果没有可到git官网进行下载:点击跳转官网下载安装包

直接下一步就可以。。。安装完成后,打开终端,输入git --version,即可显示版本。表示安装成功。

windows系统安装

到git官网进行下载:点击跳转官网下载安装包

直接下一步,可选择安装盘符。。。

安装完成后,点击右键会有Git Bash Here,点击后弹出命令行窗口,输入git --version,即可显示版本。表示安装成功。

git仓库的划分

  • Workspace:工作区,就是你在电脑里能看到的目录。

  • Index / Stage:暂存区,一般存放在 ".git目录下" 下的index文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。通过add命令将工作区内容添加到暂存区。

    .git是我们初始化目录时git自动创建的一个隐藏目录,里面存放的是我们所有的版本信息。勿动!!!

  • Repository:仓库区(或本地仓库),工作区有一个隐藏目录.git。通过commit命令将暂存区内容添加到仓库区。

  • Remote:远程仓库。通过push命令将暂存区的内容提交到远程仓库。

项目管理流程

先将项目代码fork到自己的账号下

在github或器他代码管理平台上右上方都有一个fork,表示将该用户的代码,fork到自己的账号下。

从远程仓库clone代码

最好使用clone从仓库中将项目代码克隆岛本地,如果是维护老项目,不使用clone直接进行下载的时候,在提交代码时会全部检测为新添加内容。导致无法进行code review

git clone 代码仓库的地址

初始化仓库

mac/linux系统打开终端切换到要管理的目录下,win系统可进入项目文件夹后,右键-->点击Git Bash Here,弹出终端。

# 在终端中输入下面命令,等于是让git开始管理这个目录下的所有内容了
git init

查看目录状态

git status # 查看当前目录下有哪些文件有变化,会以红色内容显示,此时文件在工作区

添加内容到本地的暂存区

git add 后面加需要管理的文件/目录
例:
git add .  # 管理当前目录下的所有内容
git add test.py # 管理当前目录下的test.py文件
# 通过git add 管理的内容在查询状态时(git status)以绿色显示,即已经被管理到暂存区

个人信息配置

# 设置提交代码时的用户信息,即告诉git是谁提交的本次代码。
$ git config --global user.name "[name]"
$ git config --global user.email "[email address]"
使用global参数表示你这台机器上所有的Git仓库都会使用这个配置,global不是非必须参数。

检查已设置的配置信息,使用$ git config --list命令

生成版本,即add后到暂存区的文件提交到本地仓库

注意:如果是初次使用git管理未进行个人信息配置,直接执行此步骤会报错,需要先进行个人配置,如上一步。

git commit -m "此处填写该版本的描述信息"

# 提交暂存区的指定文件到仓库区,只是在上述命令中加入要提交的文件名
$ git commit [file1] [file2] ... -m [message]

# 使用一次新的commit,替代上一次提交,如果代码有变化需要进行add
# 如果代码没有任何新变化,则用来改写上一次commit的提交message信息
$ git commit --amend -m "message"

# 提交时显示所有diff信息,比较鸡肋,因为每次提交时可通过git status查看状态
$ git commit -v

查看版本记录

# 查看版本
git log
# 以流程的形式显示
git log --graph
# 查看所有的提交历史,只显示版本号和描述
git log --pretty=oneline

# 显示当前分支的最近几次提交
git reflog

版本回滚

已经进行commit后进行回滚

将(工作区)本地代码回滚到某个状态

git reset --hard 版本号  # 版本号可通过git log查看,想回滚到某个状态,版本号就是谁

回滚后如果还想再回到回滚之前的版本,还是通过上述代码进行,不过使用git log无法查到版本号,需要使用git reflog。

将本地仓库的代码回滚到暂存区,即回滚到add以后的状态

git reset --soft 版本号  # 将该版本号之前的版本回滚到暂存区

已经add后回滚

将add后(即暂存区版本)回滚到工作区

git reset HEAD  # 执行完以后,再执行git status查看状态,会发现依然是红色,证明代码还在工作区。

从本地仓库直接回到工作区,即add之前状态

git reset --mix 版本号  # 该版本号的意思:将该版本号之前的版本回滚到工作区。

将本地修改撤销

git checkout .  # 撤销工作区所有未进行add的文件内容修改,只针对于文件内容的修改,新增/删除文件无法撤销
git checkout 文件名 # 撤销对某一个文件内容的修改

分支

使用场景

  1. 多人协同开发,要创建自己的分支。

  2. 如果是已经上线的项目,需要开发新功能,但是此时项目出问bug了,那么就需要你进行紧急修复。如果没有分支,本地代码可能会受到影响,还需要涉及到代码冲突问题。

    如果在开发新功能时,创建了单独的分支,那么在线上代码出问题时,可以直接切换到原来分支进行修改。

    如果线上项目是一个分支dev1,自己正在开发的新功能是一个分支dev2,那么我们在切换回dev1分支时,本地代码会自动变成dev1时的状态,当dev1的bug修复完成后,可以再次切换到dev2分支,此时代码还是你正在开发时的状态。在dev1分支上修复的bug也不见了。

分支之间的代码互不影响

查看分支

查看所有本地分支

git branch

查看所有远程分支

git branch -r

列出所有本地分支和远程分支

git branch -a

创建分支

新建一个分支但是留在当前分支

git branch dev1 # 创建dev1分支

切换分支

切换分支,并更新工作区

git checkout dev1 # 切换到dev1分支,并更新工作区代码到当前分支

新建一个分支并切换到该分支

git checkout -b dev1  # 新建一个dev1分支,并切换到dev1分支上

删除分支

删除本地分支

git branch -d dev2  # 删除dev2分支

删除远程分支

git push origin --delete 远程分支名

合并分支

git merge bug  # 合并bug分支到当前所在分支

合并分支时,会产生冲突,需要手动解决冲突后,提交。

重命名分支

本地分支重命名

git branch -m oldName newName

如果已经提交到远程仓库了,想要给远程仓库也修改名字。需要先删除远程仓库分支,然后直接git push

git branch -m dev1 develop-weida # 重命名dev1分支为develop-weida
git push origin --delete dev1    # 删除远程的dev1分支
git push origin develop-weida    # 直接推送到远程仓库,会自动创建分支

线上项目bug修复

比如:master分支是我们线上跑的代码,此时我们开发新功能,需要建立一个新分支dev1,进行新的功能开发。此时项目出现bug,我们需要在master的基础上建立一个新的分支bug分支,然后在此分支上进行bug修复。此时相当于dev1分支和bug分支都是在master(线上代码分支)分支基础上进行的。修改完bug分支没有问题后,需要将bug分支代码合并到master分支上,然后将bug分支删除。此时再切换到dev1分支上继续开发,此时dev1分支上的bug还未修复。当dev1分支功能开发完毕后,要合并到master分支,此时会有冲突,需要手动解决冲突后,然后提交。

远程仓库

增加远程仓库

git remote add origin https://github.com/xxx/xxx.git(远程仓库地址)
# origin 就是我们起的别名

将本地仓库代码推送到远程仓库

git push origin master
origin 就是建立远程仓库连接时的别名
master 就是我们要提交到哪个分支

git push origin master -force   # 将重置后的master分支强制推送更新

显示远程仓库信息

显示所有远程仓库

git remote -v

显示某个远程仓库信息

git remote show 远程仓库别名

取回远程仓库的变化,并与本地分支合并

git pull origin master

# 指定从某个远程仓库取回代码
git pull origin https://github.com/xxx/xxx.git dev1
git pull --rebase     # 从服务器拉取最新代码

将git pull拆分

git pull origin dev1
上面代码,相当于
git fetch origin dev1  # 先将远程仓库代码拉到版本库
git merge orgin/dev1   # 将版本库中的代码合并到工作区

在远程仓库拉取代码过程可能出现的问题

  1. 在公司写了一个功能的代码,忘记提交。回到家后又写了另一个功能。第二天到公司后拉取代码可能或产生冲突。需要先手动解决冲突。
  2. 可能公司的代码让你先fork到你自己的github账号,然后让你对fork的代码进行修改,修改完成后通过pull request进行合并申请,与源代码合并。可能会出现,源代码一方将代码修改了,所以你需要与源代码同步。此时删除或者重命名你本地的那个分支,然后将远程仓库的分支删除。重新在本地建立分支,在本地git pull拉取源代码仓库的代码,直接git push 到你的仓库中,然后再将你之前可能添加新功能的代码进行合并。有冲突,先手动解决冲突。

rebase

将多个提交记录整合成一个

git push之前

commit 1cfce86cb8ceb0d9b8c5a6a7f0d49a5d554b6774 (HEAD -> dev1)
Author: xxx <123456@qq.com>
Date:   Sun Dec 8 20:56:21 2019 +0800

    版本3

commit ca334aaf85270b3283a7fc6e1b5c4d69cca7a5a7
Author: xxx <123456@qq.com>
Date:   Sun Dec 8 20:36:25 2019 +0800

    版本2

commit 9e4adfceb1be1a9c5d63a71dae03fbfa5ba1d392
Author: xxx <123456@qq.com>
Date:   Sun Dec 8 19:13:13 2019 +0800

    版本1

比如现在commit上面三条记录

# 第一种,按版本号
git rebase -i 9e4adf # 9e4adf版本号之后的版本到当前版本进行合并,不包含9e4adf

# 第二种,使用HEAD
git rebase -i HEAD~3 # 从当前开始最近的三条进行合并

执行完上述合并代码后,会出现如下代码,注释内容均是命令提示。

pick ca334aa 版本2
pick 1cfce86 版本3

# Rebase 9e4adfc..1cfce86 onto 9e4adfc (2 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit 
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# .       create a merge commit using the original merge commit's
# .       message (or the oneline, if no original merge commit was
# .       specified). Use -c <commit> to reword the commit message.
#
# These lines can be re-ordered; they are executed from top to bottom.

如果想要合并,我们需要将除第一个pick以外的pick改成s,意思是使用这个commit但是合并到上一个commit。结果如下:

pick ca334aa 版本2
s 1cfce86 版本3

然后切换到命令行模式,wq保存退出,然后会让你填写提交记录。

# This is a combination of 2 commits.
# This is the 1st commit message:

版本2

# This is the 1st commit message #2:
版本3

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Sun Dec 8 20:36:25 2019 +0800
#
# interactive rebase in progress; onto 9e4adfc
# Last commands done (2 commands done):
#    pick ca334aa 版本2
#    squash 1cfce86 版本3
# No commands remaining.
# You are currently rebasing branch 'dev1' on '9e4adfc'.
#
# Changes to be committed:
#       new file:   xxx.py
#

修改如下:可以自定义写记录,我这里写成版本2 & 版本3,然后切换到命令行模式,wq保存退出即可。

# This is a combination of 2 commits.
# This is the 1st commit message:

版本2 & 版本3

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Sun Dec 8 20:36:25 2019 +0800
#
# interactive rebase in progress; onto 9e4adfc
# Last commands done (2 commands done):
#    pick ca334aa 版本2
#    squash 1cfce86 版本3
# No commands remaining.
# You are currently rebasing branch 'dev1' on '9e4adfc'.
#
# Changes to be committed:
#       new file:   xxx.py
#

将分支记录插入到master,提交记录一条线

如果使用merge合并分支,那么在使用git log --graph时,会显示分支线路,使用rebase提交记录会显示在一条线上。

git checkout dev1
git rebase master  # 将master分支上的代码与dev1合并
git checkout master 
git merge dev1     # 再将dev1上的代码合并到master上

将远程代码下拉,提交记录一条线

如果公司忘记提交到远程仓库,在家写了新的功能提交到远程仓库,那么第二天回到公司git pull会出现提交记录分叉现象。使用rebase

git fetch origin dev1
git rebase origin/dev1

执行rebase命令遇到冲突情况

遇到冲突,先手动解决冲突,解决冲突后,会提示执行git add,然后再执行git rebase --continue

快速解决冲突

使用beyond compare软件

安装

https://www.scootersoftware.com/download.php

在git中配置

git config --local merge.tool bc3 # 给工具命名
git config --local mergetool.path '/usr/local/bin/bcomp'  # 安装路径
git config --local mergetool.keepBackup false  # 解决冲突后不保留备份文件

应用beyond compare解决冲突

git mergetool

打标签tag

标签分为轻量标签(lightweight)与附注标签(annotated),打上标签提交到远程仓库后,在该仓库中的releases中会有对应的版本,可以进行下载。

附注标签

创建附注标签

# 创建附注标签
git tag -a v4.0 -m "4.0版本"
v1.1是起的版本名

# 执行上述命令后,执行git log查看记录
$ git log
commit 86c90fd71fe1b48eb07eb3660a5c48485471eb04 (HEAD -> dev1, tag: v4.0)
Author: lwd <xxx@qq.com>
Date:   Sun Dec 8 20:36:25 2019 +0800

    版本4 & hello world功能

commit 9e4adfceb1be1a9c5d63a71dae03fbfa5ba1d392
Author: lwd <xxx@qq.com>
Date:   Sun Dec 8 19:13:13 2019 +0800

    版本2

查看有哪些标签

git tag

查看标签信息与对应的提交信息

# 查看提交信息
git show v4.0

# 显示结果如下,输出显示了打标签者的信息、打标签的日期时间、附注信息,然后显示具体的提交信息
tag v4.0
Tagger: lwd <xxx@qq.com>
Date:   Mon Dec 9 21:48:41 2019 +0800

版本4.0

commit 86c90fd71fe1b48eb07eb3660a5c48485471eb04 (HEAD -> dev1, tag: v4.0)
Author: lwd <xxx@qq.com>
Date:   Sun Dec 8 20:36:25 2019 +0800

    版本4 & hello world功能

diff --git a/liuweida.py b/liuweida.py
new file mode 100644
index 0000000..95d09f2
--- /dev/null
+++ b/liuweida.py
@@ -0,0 +1 @@
+hello world
 No newline at end of file

轻量标签

另一种给提交打标签的方式是使用轻量标签。 轻量标签本质上是将提交校验和存储到一个文件中——没有保存任何其他信息。 创建轻量标签,不需要使用 -a-s-m 选项,只需要提供标签名字:

创建轻量标签

# 创建标签
git tag v4.1-lv

查看标签

git tag

查看标签信息与对应的提交信息

git show v4.1-lv

后期打标签

你也可以对过去的提交打标签。

git tag -a 标签名 版本号
git tag -a v4.2 9fceb02

远程仓库共享标签

共享标签

默认情况下,git push 命令并不会传送标签到远程仓库服务器上。 在创建完标签后你必须显式地推送标签到共享服务器上。 这个过程就像共享远程分支一样——你可以运行 git push origin [tagname]

git push origin v4.0

删除标签

删除本地仓库标签

git tag -d v4.1-lv

上述命令并不会从任何远程仓库中移除这个标签,你必须使用 git push <remote> :refs/tags/<tagname> 来更新你的远程仓库:

git push origin :refs/tags/v1.4-lw

git stash

git stash会把所有未提交的修改(包括暂存的和非暂存的)都保存起来,用于后续恢复当前工作目录。

git stash pop命令可以恢复之前缓存的工作目录。这个指令将缓存堆栈中的第一个stash删除,并将对应修改应用到当前的工作目录下。

git stash apply命令,将缓存堆栈中的stash多次应用到工作目录中,但并不删除stash拷贝。可以通过名字指定使用哪个stash,默认使用最近的stash(即stash@{0})

git stash list命令,查看现有的stash。

git stash drop命令,移除stash。

git stash show命令,后面可以跟着stash名字,可以查看指定stash的diff

git diff

# 比较工作区与暂存区
git diff  不加参数即默认比较工作区与暂存区

# 比较暂存区与最新本地版本库(本地库中最近一次commit的内容)
git diff --cached  [filename] 

# 比较工作区与最新本地版本库
git diff HEAD [filename]  如果HEAD指向的是master分支,那么HEAD还可以换成master

# 比较工作区与指定commit-id的差异
git diff commit-id  [filename] 

# 比较暂存区与指定commit-id的差异
git diff --cached [<commit-id>] [filename] 

# 比较两个commit-id之间的差异
git diff [<commit-id>] [<commit-id>]

github简单介绍

公司项目一般会建立一个组织,将你拉入组织,然后为你创建一个分支,用于提交你的代码。

你进入组织的项目,将组织中项目的代码通过github中右上角有一个fork,fork到自己的仓库。

使用git clone 将代码下载克隆到本地,进行开发。

开发完成后,提交到你自己的仓库,通过pull request合并到组织中的仓库你的分支上。会有leader进行code review。

可能会出现的情况

如果组织仓库中的代码有更新,你的leader可能会让你先通过git pull拉取一下组织中的代码,可以先将你原来本地的分支重命名或者删除,然后拉取,拉取完毕后,删除你自己远程仓库的分支,直接进行git push。

git branch -m dev1 develop-weida
git branch dev1
git pull origin https://xxxxx/xxxx.git dev  # 从组织仓库的dev分支拉取代码
git push origin --delete dev1
git push origin dev1

执行上述代码可能会有冲突,出现冲突就先手动解决冲突。如果原dev1中还有需要的代码,可以通过分支合并,将自己的新功能合并过来。

冲突

当你commit以后,在执行git pull --rebase的时候出现冲突,请按如下步骤解决:
1  找到冲突文件,解决冲突
2  执行git add xxx(xxx为冲突文件全路径)
3  执行git rebase --continue
4  执行git pull --rebase
5  执行git push

当你本地有修改的时候,你执行了git stash,然后又从服务器上pull了最新代码(git pull --rebase),出现了冲突,请按如下方式解决:
1  找到冲突文件,解决冲突
2  执行git add xxx(xxx为冲突文件全路径)
3  git commit
4  git pull --rebase
5  git push

git忽略文件

在git管理的目录下创建.gitignore文件。

在其中写入不需要管理的文件名、目录,当git管理该项目时,就不会将写入.gitignore文件中的内容管理起来。

.gitignore文件,比如,内容如下

a.py
*.h  # 忽略所有.h结尾的文件
myfile/  # 忽略myfile目录下的所有内容
!b.h  # 忽略管理时,排除b.h

github上有写好的大部分内容,可直接使用,如下:

python.gitignore文件:点击查看详细内容
        

// Byte-compiled / optimized / DLL files
pycache/
*.py[cod]
*$py.class

// C extensions
*.so

// Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

// PyInstaller
// Usually these files are written by a python script from a template
// before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

// Installer logs
pip-log.txt
pip-delete-this-directory.txt

// Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/

// Translations
*.mo
*.pot

// Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

// Flask stuff:
instance/
.webassets-cache

// Scrapy stuff:
.scrapy

// Sphinx documentation
docs/_build/

// PyBuilder
target/

// Jupyter Notebook
.ipynb_checkpoints

// IPython
profile_default/
ipython_config.py

// pyenv
.python-version

// pipenv
// According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
// However, in case of collaboration, if having platform-specific dependencies or dependencies
// having no cross-platform support, pipenv may install dependencies that don't work, or not
// install all needed dependencies.
// Pipfile.lock

// PEP 582; used by e.g. github.com/David-OConnor/pyflow
pypackages/

// Celery stuff
celerybeat-schedule
celerybeat.pid

// SageMath parsed files
*.sage.py

// Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

// Spyder project settings
.spyderproject
.spyproject

// Rope project settings
.ropeproject

// mkdocs documentation
/site

// mypy
.mypy_cache/
.dmypy.json
dmypy.json

// Pyre type checker
.pyre/

  </code>
点击此处,到github查看各种语言的gitignore文件
原文地址:https://www.cnblogs.com/liuweida/p/12008796.html