• 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文件
  • 相关阅读:
    Java生产环境线上栈故障排查问题(COPY)
    Java集合HashMap,List底层
    图算法--染色法判定二图
    图算法--kruskal
    图算法--最小生成树prim
    图算法--判负环
    图算法--floyd
    图算法--spfa
    图算法--bellman-ford (nm)
    图算法--堆优化版dijkstra
  • 原文地址:https://www.cnblogs.com/liuweida/p/12008796.html
Copyright © 2020-2023  润新知