zoukankan      html  css  js  c++  java
  • Git使用教程

    基本背景

    Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的分布式版本控制系统。
    它采用了分布式版本库的方式,不必服务器端软件支持(注:这得分是用什么样的服务端,使用http协议或者git协议等不太一样。并且在push和pull的时候和服务器端还是有交互的),使源代码的发布和交流极其方便。

    Git与SVN区别

    Git 不仅仅是个版本控制系统,它也是个内容管理系统(CMS),工作管理系统等。

    如果你是一个具有使用 SVN 背景的人,你需要做一定的思想转换,来适应 Git 提供的一些概念和特征。

    Git 与 SVN 区别点,这里借用菜鸟教程的一张图说明:

    图片名称
    1、Git 是分布式的,SVN 不是:这是 Git 和其它非分布式的版本控制系统,例如 SVN,CVS 等,最核心的区别。

    2、Git 把内容按元数据方式存储,而 SVN 是按文件:所有的资源控制系统都是把文件的元信息隐藏在一个类似 .svn、.cvs 等的文件夹里。

    3、Git 分支和 SVN 的分支不同:分支在 SVN 中一点都不特别,其实它就是版本库中的另外一个目录。

    4、Git 没有一个全局的版本号,而 SVN 有:目前为止这是跟 SVN 相比 Git 缺少的最大的一个特征。

    5、Git 的内容完整性要优于 SVN:Git 的内容存储使用的是 SHA-1 哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏。

    安装

    window下的安装及海龟Git的安装配置

    参考window下git及TortoiseGit的安装

    Centos/Redhat系列安装

    在终端下执行 yum install git
    

    Ubuntu/Debian系列安装

    在终端下执行 apt-get install git 
    

    编译安装

    在https://github.com/git/git/releases 上选取一个版本下载,解压缩后进入到 Git 的目录然后依次执行以下代码:

    make configure
    ./configure
    make all
    sudo make install
    

    代码管理

    Git 工作区、暂存区和版本库

    • 工作区:就是你在电脑里能看到的工作目录,某个项目文件夹。
    • 暂存区:英文叫stage, 或index。一般存放在 ".git目录下" 下的index文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
    • 版本库:工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库
    图片名称
    图中左侧为工作区,右侧为版本库。在版本库中标记为 "index" 的区域是暂存区(stage, index),标记为 "master" 的是 master 分支所代表的目录树。

    图中我们可以看出此时 "HEAD" 实际是指向 master 分支的一个"游标"。所以图示的命令中出现 HEAD 的地方可以用 master 来替换。

    图中的 objects 标识的区域为 Git 的对象库,实际位于 ".git/objects" 目录下,里面包含了创建的各种对象及内容。

    我们把文件往Git版本库里添加的时候,是分两步执行的:

    • 第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;
    • 第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。

    版本控制

    git reset --hard 简洁/完整哈希索引值:回到指定哈希值所对应的版本
    
    git reset --hard HEAD:强制工作区、暂存区、本地库为当前HEAD指针所在的版本
    
    git reset --hard HEAD^:后退一个版本  
    
      tip:一个^表示回退一个版本
    
    git reset --hard HEAD~1:后退一个版本
    
      tip:波浪线~后面的数字表示后退几个版本
    

    由上我们可以看出 "HEAD" 实际是指向 master 分支的一个"游标"。所以图示的命令中出现 HEAD 的地方可以用 master 来替换。
    git reset HEAD 命令用于取消已缓存的内容;
    当执行 "git reset HEAD" 命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。
    假设当前工作目录下有两个文件test.txt、test1.txt现在两个文件修改后,都提交到了缓存区,我们现在要取消其中一个的缓存,操作如下:

    $ git status -s
    ?? test.txt
    ?? test1.txt
    $ git add .
    $ git reset HEAD test1.txt
    $ git status
    On branch master
    Your branch is up to date with 'origin/master'.
    
    Changes to be committed:
      (use "git restore --staged <file>..." to unstage)
            new file:   test.txt
    
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
            test1.txt
    
    

    提交代码

    1. (从现有仓库克隆)仓库clone到本地,修改后再push到远程仓库
    #将远程仓库克隆到本地
    git clone https://github.com/用户个性地址/PictureBed.git 
    git clone git@github.com:TAT123/PictureBed.git
    

    用户也可以通过配置本地的git配置信息,执行git config命令预先配置好相关的用户信息,配置执行如下:

    git config --global user.name "你的名字或昵称"
    git config --global user.email "你的邮箱"
    

    平台上的提交邮箱与上面配置信息中的邮箱地址保持一致,这样平台就能及时地统计你在平台中提交代码的贡献了。
    修改代码后,在仓库目录下执行下面命令:

    #将当前目录所有文件添加到git暂存区
    git add . 
    #提交并备注提交信息
    git commit -m "my first commit" 
    #将本地提交推送到远程仓库
    git push origin master 
    
    1. (工作目录中初始化新仓库)本地初始化一个仓库,设置远程仓库地址后再做push
      和方法1的差别,在于先创建仓库。
    git init 
    git remote add origin https://gitee.com/用户个性地址/HelloGitee.git
    git pull origin master
    

    新建仓库时,如果在平台仓库上已经存在 readme 或其他文件,在提交时可能会存在冲突,这时用户需要选择的是保留线上的文件或者舍弃线上的文件,如果您舍弃线上的文件,则在推送时选择强制推送,强制推送需要执行下面的命令(默认不推荐该行为):

    git push origin master -f
    

    如果您选择保留线上的 readme 文件,则需要先执行:

    git pull origin master
    

    分支管理

    #创建分支
    git branch (branchname)
    #切换分支
    git checkout (branchname)
    #创建并切换到该分支
    git checkout -b (branchname)
    #列出分支
    git branch
    #删除分支
    git branch -d (branchname)
    
    • 分支合并 git merge

    我们创建了一个分支dev,在该分支的上移除了一些文件 test1.txt,然后切换回我们的主分支,删除的 test1.txt 文件又回来了。

    $ git checkout -b dev
    Switched to a new branch 'dev'
    
    $ git rm test1.txt
    rm 'test1.txt'
    
    $ ls
    img/  README.md  test.txt
    
    $ git add .
    
    $ git commit -am 'remove test1.txt'
    [dev aeb6d8d] remove test1.txt
     1 file changed, 1 deletion(-)
     delete mode 100644 test1.txt
    
    $ git checkout master
    
    $ ls
    img/  README.md  test.txt  test1.txt
    

    使用分支将工作切分开来,从而让我们能够在不同开发环境中做事,并来回切换。我们将 dev 分支合并到主分支去,test.txt 文件被删除。

    $ git merge dev
    Updating 4f9f7b3..aeb6d8d
    Fast-forward
     test1.txt | 1 -
     1 file changed, 1 deletion(-)
     delete mode 100644 test1.txt
    
    git branch
      dev
    * master
    
    ls
    img/  README.md  test.txt
    

    解决冲突 git merge

    # 在本分支合并其他分支
    git merge change_site
    # 查看冲突
    git diff
    # 要告诉 Git 
    git add
    
    

    我们创建一个叫做 change_site 的分支,切换过去,我们将 test.txt 内容修改并且提交,切换回master分支我们可以看内容恢复到我们修改前的,我们再次修改 test.txt 文件:

    $ git checkout -b change
    Switched to a new branch 'change'
    
    $ ls
    img/  README.md  test.txt
    
    $ cat test.txt
    hello git
    $ echo 'test change merge' >> test.txt
    
    $ git commit -am "test merge"
    
    #切换回master
    $ git checkout master
    Switched to branch 'master'
    $ echo 'test master merge' >> test.txt
    
    $ git diff
    diff --git a/test.txt b/test.txt
    index 8d0e412..4815a4a 100644
    --- a/test.txt
    +++ b/test.txt
    @@ -1 +1,2 @@
     hello git
    
    $ git commit -am '修改代码'
    
    #查看test.txt的内容
    $ cat test.txt
    hello git
    <<<<<<< HEAD
    test master merge
    =======
    test change merge
    >>>>>>> change
    
    #手动修改冲突文件后再提交
    git add test.txt
    git commit -m 'merge change'
    
    $ cat test.txt
    hello git
    
    test master merge
    
    test change merge
    
    

    更详细的可以查看廖雪峰的网站

    仓库管理

    本地仓库与远程仓库交互

    git clone <远程库地址>:克隆远程库
    
      功能:①完整的克隆远程库为本地库,②为本地库新建origin别名,③初始化本地库
    
    git remote -v:查看远程库地址别名
    
    git remote add <别名> <远程库地址>:新建远程库地址别名
    
    git remote rm <别名>:删除本地中远程库别名
    
    git push <别名> <分支名>:本地库某个分支推送到远程库,分支必须指定
    
    git pull <别名> <分支名>:把远程库的修改拉取到本地
    
      tip:该命令包括git fetch,git merge
    
    git fetch <远程库别名> <远程库分支名>:抓取远程库的指定分支到本地,但没有合并
    
    git merge <远程库别名/远程库分支名>:将抓取下来的远程的分支,跟当前所在分支进行合并
    
    git fork:复制远程库
    
      tip:一般是外面团队的开发人员fork本团队项目,然后进行开发,之后外面团队发起pull request,然后本团队进行审核,如无问题本团队进行merge(合并)到团队自己的远程库,整个流程就是本团队跟外面团队的协同开发流程,Linux的团队开发成员即为这种工作方式。
    

    公钥管理

    公钥配置

    公钥配置参考

    Git配置多个SSH-Key

    参考配置多个ssh密钥配置
    我的配置:

    # 添加config配置文件
    
    # 文件内容如下:
    # gitee
    Host gitee.com
        HostName gitee.com
        PreferredAuthentications publickey
        IdentityFile ~/.ssh/id_rsa
    	User zfl
    
    # gitlab
    Host gitlab.com 
        HostName gitlab.com
        PreferredAuthentications publickey
    	Port 60019
        IdentityFile ~/.ssh/id_rsa
    	User zfl
    # github
    Host github.com
        HostName github.com
        PreferredAuthentications publickey
        IdentityFile ~/.ssh/github_id_rsa    
        User zfl
    # 配置文件参数
    # Host : Host可以看作是一个你要识别的模式,对识别的模式,进行配置对应的的主机名和ssh文件
    # HostName : 要登录主机的主机名
    # User : 登录名
    # IdentityFile : 指明上面User对应的identityFile路径
    

    工作流程

    图片名称
    多人协作的工作模式通常是这样:
    1. 首先,可以试图用git push origin 推送自己的修改;

    2. 如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;

    3. 如果合并有冲突,则使用git diff查看冲突,git status查看冲突文件,解决冲突,并在本地提交;
      没有冲突或者解决掉冲突后,再用git push origin 推送就能成功!

    4. 如果git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to origin/
      更详细的可以查看廖雪峰的网站

    这篇博客是为了给实验室新生培训用的,一些地方讲的也不是很全,日后有机会会完善一下。

  • 相关阅读:
    今日头条、Face++开发岗面经
    美团offer面经
    成都百度测试开发一二面面经
    美团四面面经
    久邦数码(3G门户)面试
    58 面试
    好未来提前批
    百度提前批
    新浪面经
    Java Programs
  • 原文地址:https://www.cnblogs.com/skills/p/13513595.html
Copyright © 2011-2022 走看看