美文网首页git
Git使用,实战版

Git使用,实战版

作者: foxleezh | 来源:发表于2016-10-22 18:21 被阅读0次

    Git安装

    Git配置

    配置快捷命令

    • 在用户根目录下(如C:/user/Administrator)新建配置文件命名为.gitconfig
    • 将以下内容写入文件
    [user]
        email = xxx(邮箱如:foxleezh@gmail.com)
        name = xxx(名字如:foxleezh)
    [alias]
        st = status
        ci = commit
        br = branch
        co = checkout
        glog = log --pretty=oneline
        pus = push
        pul = !git pull --rebase && git submodule update --init --recursive
        lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
    [merge]
        tool = vim
    [core]
        packedGitLimit = 512m
        packedGitWindowSize = 512m
    [pack]
        deltaCacheSize = 2047m
        packSizeLimit = 2047m
        windowMemory = 2047m
    

    配置ssh

    • 在命令行输入
    ssh-keygen -t rsa
    
    • 在用户目录(如C:/user/Administrator)打开.ssh文件夹,查看id_rsa.pub文件,将密钥拷贝到服务器密钥库

    配置忽略文件

    • 将.gitignore文件放置到项目根目录下
    # OSX
    
    *.DS_Store
    
    
    # Gradle files
    build/
    build_out/
    obj/
    .gradle/
    */build/
    captures/
    
    gradle/
    # IDEA
    *.iml
    .idea/.name
    .idea/encodings.xml
    .idea/inspectionProfiles/Project_Default.xml
    .idea/inspectionProfiles/profiles_settings.xml
    .idea/misc.xml
    .idea/modules.xml
    .idea/scopes/scope_settings.xml
    .idea/vcs.xml
    .idea/workspace.xml
    .idea/libraries
    .idea/runConfigurations.xml
    .idea/compiler.xml
    .idea/copyright/profiles_settings.xml
    .idea/gradle.xml
    .idea/
    
    # Built application files
    *.ap_
    
    
    # Files for the Dalvik VM
    *.dex
    
    
    # Java class files
    *.class
    
    
    # Local configuration file (sdk path, etc)
    local.properties
    
    
    # Log Files
    *.log
    
    # Special
    gradle.properties
    
    • 凡是在列表中的文件(*表示所有)都将被git忽略,对这些文件的任何改动,git都不会追踪
    • 但是有时我们只想追踪某几个文件,其它都忽略,可以如下配置,!后面的内容为追踪的文件
    /*
    !.gitignore
    !README.md
    

    Git使用

    一.准备工作

    • 新建仓库(进入到项目的根目录下)
    git init
    
    • 添加忽略规则,将.gitignore文件放置到根目录下
    • 添加文件,将需要管理的文件加入到根目录下

    二.代码管理

    • 查看状态
    git st
    

    红色表示已修改未保存到缓存区,绿色表示已保存到缓存区

    Git有三个状态,一是修改未保存到缓存,二是保存到缓存,三是提交到版本库

    我们可以对比着word文档来学习,状态一就相当于你在word中修改了一些东西,但是没有按ctrl+s键保存起来,状态二就是你修改了东西后按了ctrl+s,暂时存起来了,状态三就是点击了另存为,将它另外存放起来了

    • 保存到缓存区
    git add 文件路径(添加单个文件到缓存)
    

    一开始修改了homepage和loading两个文件,git st后显示红色

    使用git add后,将homepage加入到缓存区

    git st后,发现homepage变为绿色

    git add -u(添加所有修改到缓存)
    

    一开始修改了homepage和loading两个文件,git st后显示红色

    使用git add -u后,将homepage和loading一起加入到缓存区

    git st后,发现homepage和loading变为绿色

    git add . (添加所有文件到缓存,包括新建的文件)
    

    此用法与git add -u类似,区别在于,git add -u只能将修改的文件加入缓存,如果该文件是新建的,要使用git add ., 这个“.”符号表示所有

    • 撤销缓存区的文件
         git reset 文件路径(撤销单个文件)
    

    首先git st后发现,有两个已经加入到缓存区的homepage和loading文件

    使用git reset homepage后,将homepage文件撤销

    git st后发现,homepage变为红色

    git reset(撤销所有缓存区的文件)
    

    首先git st后发现,有两个已经加入到缓存区的homepage和loading文件

    使用git reset后,将所有文件撤销

    git st后发现,homepage和loading都变为红色

    • 撤销修改
    git co 文件路径(撤销单个文件的修改)
    

    首先使用git st,发现有homepage和loading两个文件被修改

    使用git co homepage,撤销homepage的修改

    git st后发现homepage文件不见了,查看原代码,代码中的修改也没有了

    git reset --hard (撤销所有文件的修改)
    

    首先使用git st,发现有homepage和loading两个文件被修改

    使用git reset --hard,撤销所有的修改

    git st后发现homepage和loading文件不见了,显示nothing to commit,working directory clean, 这表示当前没有任何的修改

    • 查看修改的内容
    git diff 文件路径(查看单个文件修改)
    

    首先使用git st,有两个文件Homepage,loading被修改

    使用git diff homepage,可以看到哪些被修改了,按箭头上下可以翻动,”-”号表示删除(红色显示),”+”号表示添加(红色显示)

    查看完成后输入q,即可退出查看

    要查看所有修改直接用git diff

    git diff --cached (查看处于缓存区的修改)
    

    首先使用git st,有两个文件Homepage,loading被加入到缓存区

    使用git diff homepage,可以看到哪些被修改了,按箭头上下可以翻动,”-”号表示删除(红色显示),”+”号表示添加(红色显示)

    查看完成后输入q,即可退出查看

    要查看所有修改直接用git diff --cached

    • 将缓存区的内容提交到版本库
    git ci -m “我修改了什么”
    

    首先git st,发现有两个文件homepage和loading加入到缓存区

    使用git ci -m “注释”,将缓存区的内容提交到版本库,这里注释是随便写的,用于提示该commit修改了一些什么内容

    git st后发现,缓存区中的内容不见了,这是因为已经提交到版本库中了

    • 查看版本库中的内容
    git log
    

    git log后发现有两个提交,“我修改了什么”是刚刚提交的commit,下面来分析下:

    commit ac76744b1843665d0c6cf1add7cf758bc824c89a (这行是一个md5值,用来唯一标识commit的)

    Author: foxleezh foxleezh@gmail.com (这行是说明该commit是谁提交的)

    Date: Fri Jul 10 10:02:16 2015 +0800 (提交的时间)

    我修改了什么 (之前我们写的注释)

    • 查看某个提交中修改的内容
    git show commit号
    

    git show ac76744b, 这个ac76744b就是之前git log时对应的md5值,可以只取前6位

    查看完成用q退出

    我们回顾一下已讲的内容,一般来说使用流程都是

    • 修改了一些内容,用git st看看状态
    • git diff看看修改了哪些内容
    • 确认无误后,将需要提交的内容git add加入到缓存区
    • git ci -m 加入到版本库中,这里说一下,平常我们都用git ci -m新建一个commit,其实通常我们不用新建commit,而是用git ci --amend追加的方式

    这里我们修改了loading中的内容,然后git add -u 加入到缓存区,因为我们只是修改了很少的内容,不需要重新提交commit,所以使用git ci --amend追加到之前的commit,这时会让我们修改注释内容

    这是一个vim的编辑器,之前linux中有讲,按i进入编辑模式,箭头移动光标就可以修改注释,修改好后,按ESC进入一般模式,按:进入命令模式,输入wq,保存退出

    git log后发现没有新建commit,只是追加到了之前的commit

    我们在使用的过程中可能要回到某一个提交,这时可以使用git reset命令,这个命令可以带参数,--mixed(回到修改未保存状态),--soft(回到缓存区状态),--hard(删除所有修改),默认是--mixed

    先讲讲--hard,这个好理解,就是把这个commit之后的所有修改都删除

    这里有四个commit

    我们先使用git reset --hard ,将“我修改了名字”之后的所有修改的删除

    git st后发现,没有任何修改

    git log后,已经回到”我修改了名字”的commit

    下面我们试试git reset --mixed或者git reset

    git log我们会发现--mixed和--hard都回到了“我修改了名字”的版本,区别在于git st后--mixed将“测试reset1”和“测试reset2”中修改的内容保留下来了,这样好处在于,我们有时回到某一个commit不是要删除所有的修改,而是只想改变某一些东西,这时我们把需要改的地方改掉后,再重新提交一个commit,这样会方便很多

    最后我们试试git reset --soft

    这个跟git reset --mixed差不多,只是它是把之后的修改放入了缓存区

    三.分支操作

    之前我们的操作都是同一个分支上的操作,现在我们引入分支的概念

    • 查看分支
    git br
    

    git默认都会有一个分支叫master,这个分支叫主分支,一般来说我们提交代码的时候是用这个分支来提交,但是实质上它跟普通的分支没有什么区别

    为什么我们要引入分支,svn也有分支的概念,但是基本是在服务器端,我们本地基本是在一个分支上修改内容的,然后commit,有时我们改一个东西A可能需要很长时间,当还没有改完却突然要修改另外一个东西B,而且A因为没有改完不能合并到版本库,这时svn就有点乏力了,我们可能要把之前没改完的东西A删除掉,然后再来改接下来的B。

    git因为是分布式的,不管是服务器端还是本地,都可以存在很多分支,这样就方便我们利用分支很好地管理代码,当我们修改任务A的时候,我们可以在分支A上修改,分支A在master的基础上新建而来,当我们还没有处理完A就要处理B时,我们可以新建另一个分支B,也是在master的基础上新建而来,这样当我们处理完B,提交后,可以回到A,继续我们之前的开发,当我们开发完A,要提交的时候,我们把B的内容整合进来,这个涉及到分支合并,我们之后再讲

    • 新建分支
    git co -b TEST  //新建名为TEST的分支,当前的分支会以绿色显示
    

    当我们新建分支时,是从当前分支的基础上新建的,新建的分支保留了当前分支所有的修改,所以新建分支相当于对当前分支的一份拷贝,而不是一个空的分支

    • 切换分支
    git co master  //切换到master分支
    
    • 删除分支
    git br -D TEST //D大写,表示强制删除
    
    • 分支合并
      讲合并,我们就回到之前那个例子,我们处理A任务和B任务都新建一个分支分别为TESTA和TESTB,这两个分支都是在master的基础上新建过来的

    这里有三个分支,分别是master,TESTA,TESTB

    主分支master有两个提交

    git co TESTA切换到TESTA,上面有三个提交,在master基础上多了一个“测试A”的提交

    git co TESTB切换到TESTB,上面有三个提交,在master基础上多了一个“修改B”的提交

    现在我们需要把A和B合并到一起

    首先切换到TESTA分支,然后使用git rebase TESTB命令,将TESTB合并到TESTA前面

    一般来说,如果两个分支没有冲突的话,合并就完成了,像上图有冲突就需要解决冲突

    git st后发现,TESTA和TESTB都修改了loading文件

    git diff loading后,查看具体的冲突内容,git用特殊的符号标记冲突,<<<<<< HEAD到=======之前是你要合并的分支对当前文件的修改,因为现在我是要把TESTB合并到TESTA,所以HEAD就代表TESTB的修改,也就是“我是用来追加的B”是TESTB的修改,然后======与>>>>>>之前的内容是TESTA的修改,也就是“我是用来追加的A”这句话

    现在我们要做的就是确认好是保留A的内容,还是保留B的内容,还是A和B的内容都保留,我们修改可以用linux的vim工具来修改,也可以直接在Android studio或者xcode中修改,修改时先将<<<<<,======这些特殊标记符号去掉,然后再进行修改

    修改完成后,git add -u 将修改的内容加入到缓存区

    然后git rebase --continue,继续rebase操作

    如果要放弃合并,使用git rebase --abort

    合并完成后git log,我们可以看到,TESTB的修改“修改B”已经合并进TESTA了,这时TESTA分支中就包含了A和B的修改

    四.与远程服务器交互

    • 生成rsa密钥
    ssh-keygen -t rsa
    

    查看id_rsa.pub文件,将密钥拷贝到服务器密钥库

    • 从远程复制仓库
    git clone 服务器仓库地址
    

    一般来说是新建一个空目录,然后去克隆服务器的git仓库

    • 在服务器添加仓库

    1.新建本地仓库

    git init
    

    2.添加远程仓库地址

    git remote add origin ssh://****@****:29418/foxleezh/test.git
    

    3.提交远程仓库

    git push origin master
    

    4.切换到远程分支

    git br -r 查看远程分支
    git co 切换到某一个远程分支
    

    5.删除远程分支

    git push origin :branch
    

    6.拉取服务器分支并切换到临时分支

    git fetch origin branchname && git co FETCH_HEAD
    

    如:
    git fetch origin GIT && git co FETCH_HEAD

    7.拉取服务器分支并合并到master

     git pull
    

    pull命令相当于fetch命令加上merge命令,将服务器master分支的内容拉下来并合并到本地master

    git pull --rebase
    

    以rebase形式拉取,相当于fetch命令加上rebase命令

    如果是pull其他分支,加上分支名

    git pull origin branchA
    

    8.向服务器提交分支

    git push
    

    如果是push其他分支,加上分支名

    git pull origin branchA
    

    9.常见错误

    • unable to rewind rpc post data - try increasing http.postBuffer
    git config http.postBuffer 524288000
    
    • 高版本不支持ssl
    Host www.xxx.com(改成服务器地址)
    HostkeyAlgorithms ssh-dss
    

    五.子模组

    • 新建子模组

    1.新建父项目、子项目并上传服务器
    2.克隆父项目、子项目到不同目录

    git clone ssh://<username>@<hostname>:29418/project-1.git
    git clone ssh://<username>@<hostname>:29418/lib1.git
    git clone ssh://<username>@<hostname>:29418/lib2.git
    

    3.将子项目变为父项目的子模组

    git submodule add ssh://<username>@<hostname>:29418/lib1.git libs/lib1(这里目录可以自由更改)
    git submodule add ssh://<username>@<hostname>:29418/lib2.git libs/lib2
    

    4.将父项目修改的修改提交服务器

    git add -u
    git push
    

    至此,子模组新建完成

    • 修改子模组

    1.进入子模组目录提交并上传

    git add -u
    git push
    

    2.进入父项目提交并上传

    git add -u
    git push
    
    • 克隆子模组

    1.克隆父项目

    git clone --recursive ssh://<username>@<hostname>:29418/project-1.git
    

    2.切换子项目分支
    到子目录下(此时分支处于游离状态)

    git co -b newBranch
    
    • 更新子模组

    1.在父目录下更新

    git pull
    git submodule update
    

    2.切换子项目分支
    此时分支处于游离状态

    git co -b newBranch
    
    • 删除子模块(分4步走)

    1.根据路径删除子模块的记录

    $ git rm --cached [path]
    

    2.编辑“.gitmodules”文件,将子模块的相关配置节点删除掉

    清理子模块配置

    3.编辑“ .git/config”文件,将子模块的相关配置节点删除掉

    清理子模块配置

    4.手动删除子模块残留的目录

    清理脏文件

    六、其他

    • Git找回commit
    git reflog
    
    • 开发流程(以master为例)

      • 在master的基础上新建一个分支进行修改
        git co -b newbranch
      • 在新的newbranch上改好代码后commit
        git add -u

        git ci -m "newbranch的修改"
      • 切换到master上拉取最新代码,防止别人上传了代码自己却没有更新
        git co master

        git pull origin master
      • 如果服务器有代码更新,切换回newbranch合并服务器新增代码(如果没有更新,直接执行第5步)
        git co newbranch

        git rebase master
      • 切换到master,合并newbranch代码
        git co master

        git rebase newbranch
      • 提交代码到服务器
        git push origin master
    • 有关git rebase的常识

      • 对于rebase的顺序

        比如 上例中newbranch和master两个分支的合并

        一开始两分支commit都是1,2,3

        后来newbranch提交了一个4,commit就是1,2,3,4的顺序

        而master拉取服务器更新了5,commit就是1,2,3,5的顺序

        这时我们切换到newbranch,去rebase master,即git rebase master

        rebase后的顺序是1,2,3,5,4

        如果我们当初是切换到master,去rebase newbranch

        rebase后的顺序是1,2,3,4,5

        这里的法则就是,去rebase哪个分支,就把哪个分支塞在下面
      • 对于rebase冲突的解决

        当我们rebase后,看见有冲突,git st后可以看到冲突的文件

        我们通过Android studio找到冲突的文件,去搜索=====或者<<<<<<这些特殊标记就会找到冲突的代码

        修改冲突的代码为你想要的代码后,记得将=====,<<<<<这些特殊符号去掉

        修改好后git add -u,将修改的代码提交到缓冲区

        git rebase --continue继续rebase,这样就将冲突解决了

        如果rebase过程中想取消,git rebase --abort
      • 能过rebase删除某几个commit

        比如newbranch上的commit为1,2,3,4

        这时我想将中间的2和3去掉,变为1,4

        我们首先要将2和3的commit号记下,比如是commit2,commit3

        然后git rebase --onto commit2空格commit3(commit2后面的是前一个的意思,这个符号在键盘的数字6上面)

        其实可以是git rebase --onto commit1空格commit3(因为commit2^就是commit1)
    • 一些Linux常用命令
      tab 补全命令

      ctrl+c 停止执行
      • 文件管理
        • pwd 打印当前目录

        • cd 进入某个目录
          cd /home/develop 进入绝对路径

          cd eclipse 进入相对路径

          cd ../ 返回上一级目录

        • touch [file name]打开或创建一个文件

        • mkdir -p [dir name] 创建一个目录 -p为强制创建

        • rm -r [file name/dir name] 删除一个文件或目录

        • ls -al 列出所有文件(包括隐藏文件)的详细信息
          -d 只列出该目录的信息

        • cp -rd [目标文件] [目的文件] 复制文件
          -r是允许目录cp

          -d是在拷贝软连接时只拷贝软连接,如果不加则会把原文件一起拷过去

          cp -rd test.txt dir/test.txt

        • mv -i [目标文件] [目的文件] 移动文件
          -i是询问是否覆盖同名文件,如果[目标文件][目的文件]相同,那就是重命名

        • find [dn] [参数]
          如:find $HOME -name 'foxlee' -o -type f -o -size +20M

          -atime +n :访问或执行时间大于n天的文件

          -ctime +n :写入、更改inode属性(例如更改所有者、权限或者连接)时间大于n天的文件

          -mtime +n :写入时间大于n天的文件

          文件的 Access time,atime 是在读取文件或者执行文件时更改的。

          文件的 Modified time,mtime 是在写入文件时随文件内容的更改而更改的。

          文件的 Create time,ctime 是在写入文件、更改所有者、权限或链接设置时随 Inode 的内容更改而更改的。

          因此,更改文件的内容即会更改 mtime 和 ctime,

          但是文件的 ctime 可能会在 mtime
          未发生任何变化时更改,例如,更改了文件的权限,但是文件内容没有变化。

          这里讲一下ls中显示的时间

          ls -lc filename 列出文件的 ctime

          ls -lu filename 列出文件的 atime

          ls -l filename 列出文件的 mtime

          继续讲find的参数

          -name 'filename' 直接查找该文件名的文件(注意加引号)

          -type type :通过文件类型查找 type 包含了 f, b, c, d, l, s 等等

          d 表示该文件为目录;

          f 表示该文件为普通文件;

          b 表示该文件为块设备文件,比如磁盘分区

          l 表示该文件为连接文件(linux file),上边提到的软连接即为该类型;

          c 表示该文件为串行端口设备,例如键盘、鼠标。

          s 表示该文件为套接字文件(socket),用于进程间通信。

      • 文件查看与编辑
        • vim [fn] 编辑文件 有三种模式(一般模式,编辑模式,命令模式),可以自由切换

          一般模式下移动光标(esc回到一般模式)

          箭头上下左右

        • 一般模式下查找与替换
          /word 向光标之后寻找一个字符串名为word的字符串,当找到第一个word后,按”n”继续搜后一个,"N"前一个

        • 一般模式下删除、复制粘贴
          dd 删除光标所在的那一行

          yy 复制光标所在的那行

          p,P p复制的数据从光标下一行粘贴,P则从光标上一行粘贴

          u 还原过去的操作

        • 进入编辑模式(按i进入)
          i 在当前字符前插入字符

        • 命令模式(按:进入)
          :q! 不管编辑或未编辑都不保存退出

          :wq 保存,退出

          :e! 将文档还原成最原始状态

          :set nu 在每行的行首显示行号

          :set nonu 取消行号

    相关文章

      网友评论

        本文标题:Git使用,实战版

        本文链接:https://www.haomeiwen.com/subject/tjshuttx.html