美文网首页
Git 复习重新开始

Git 复习重新开始

作者: ismyshellyiqi | 来源:发表于2018-03-20 11:02 被阅读0次
    image.png
    • 全局配置
    $ git config --global user.name "Your Name"
    $ git config --global user.email "email@example.com"
    
    • 初始化
    git init
    
    
    • 添加到暂存区
    //git add a.txt
    git add .
    
    • 添加到本地的版本库
    git commit -m 'des'
    
    • 查看当前的状态
    git status
    
    • 打印commit记录
    git log
    //git log --pretty=oneline
    
    • 回退版本
    git reset --hard HEAD^
    git reset --hard HEAD^^
    git reset --hard 'commit id'
    
    • 查看所有记录
    git reflog
    
    • 撤销修改

    场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file

    场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD file,就回到了场景1,第二步按场景1操作。

    场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,参考版本回退一节,不过前提是没有推送到远程库

    • 删除文件
    rm a.txt
    git status
    //  1 确认要删除
    git rm a.txt
    git commit -m 'des'
    
    // 2删错,想要回退
    $ git checkout -- test.txt 
    

    git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。

    命令git rm用于删除一个文件。如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容。

    • 创建ssh key

    先查看用户主目录下有没有.ssh 如果有进入,查看id_rsa(私钥),id_rsa.pub(公钥),使用的事公钥,

    cat id_rsa.pub
    

    如果没有.ssh,则需要创建

    $ ssh-keygen -t rsa -C "youremail@example.com"
    
    • 添加远程仓库
    $ git remote add origin git@github.com:<your name>/learngit.git
    
    $ git push -u origin master
    Counting objects: 19, done.
    Delta compression using up to 4 threads.
    Compressing objects: 100% (19/19), done.
    Writing objects: 100% (19/19), 13.73 KiB, done.
    Total 23 (delta 6), reused 0 (delta 0)
    To git@github.com:michaelliao/learngit.git
     * [new branch]      master -> master
    Branch master set up to track remote branch master from origin.
    

    由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。

    $ git push origin master
    
    • 从远端克隆
    $ git clone
    
    • 创建与合并分支
    // 创建并且切换分支到dev
    git checkout -b dev
    //  等同于
    git branch dev
    git checkout dev
    
    git status 
    *dev
     master
    
    git add . 
    git commit -m 'des'
    
    git checkout master
    git merge dev
    git checkout dev
    // 删除dev分支
    git branch -d dev
    

    这次合并是“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度非常快。

    • 解决冲突
    git branch -b feature1
    
    

    修改read.txt

    git add .
    git commit -m 'and'
    git checkout master
    

    在master read.txt也修改

    git add .
    git commit -m 'AND'
    git merge dev
    

    就会产生冲突

    git status
    <<<<<<< HEAD
    Creating a new branch is quick AND simple.
    =======
    Creating a new branch is quick and simple.
    >>>>>>> feature1
    

    然后保留一个修改,删除另一个

    git add .
    git commit -m 'merge'
    // 查看合并情况
    git log --graph --pretty=oneline --abbrev-commit
    
    // 删除分支feature1
    git branch -d feature
    
    • 分支管理策略

    通常,合并分支时,如果可能,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。

    如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息

    下面我们实战一下--no-ff方式的git merge:

    首先,仍然创建并切换dev分支

    git branch -b dev
    // 修改一些文件
    git add .
    git commit -m 'done'
    git checkout master
    

    使用 --no-ff合并分支

    git merger --no-ff -m '--no-ff merger test' dev
    // 查看合并的状态
    $ git log --graph --pretty=oneline --abbrev-commit
    *   7825a50 --no-ff merger test
    |\
    | * 6224937 done
    |/
    *   59bc1cb conflict fixed
    ...
    
    • bug分支

    在dev分支开发是,工作到一半的时候,可能还需要一定时间才能完成(还未提交),但是此时此需要一个小时来解决一个Bug

    可以是使用

    git stash
    

    把现在的工作现场保存起来在使用git status就会发现工作区是clear的
    然后选定在哪个分支上进行修改bug,这里假设是在master分支上修改的

    git checkout master
    git branch -b issue101
    // 假设已经修改了一些代码
    git add .
    git commit -m 'done'
    
    // 合并
    git checkout master
    git merge --no-ff -m 'issue-101 fixed' issue101 
    

    此时bug修改完毕,切换到dev分支

    git checkout dev
    git status
    
    

    会发现dev分支的工作区是clear的

    git stash list 
    stash@{0}: WIP on dev: 6224937 add merge
    

    工作现场还在,Git把stash内容存在某个地方了,但是需要恢复一下,有两个办法:

    一是用git stash apply恢复,但是恢复后,stash内容并不删除,你需要用git stash drop来删除;

    另一种方式是用git stash pop,恢复的同时把stash内容也删了

    git stash pop
    git stash list
    //会发现是空的
    

    你可以多次stash,恢复的时候,先用git stash list查看,然后恢复指定的stash,用命令:

    $ git stash apply stash@{0}
    
    • feature分支

    新的功能

    git checkout -b feature2
    
    

    一段时间后开发完成

    git add .
    git commit -m 'feature'
    // 切回到dev分支
    git checkout dev
    
    

    由于种种原因 决定放弃这个功能(但是此时还没合并分支)

    git branch -d feature2
    error: The branch 'feature2' is not fully merged.
    If you are sure you want to delete it, run 'git branch -D feature2'.
    
    $ git branch -D feature1
    Deleted branch feature1 (was 756d4af).
    
    • 多人协作

    查看远程分支

    git remote
    origin
    

    或者

    git remote -v
    origin  git@github.com:<name>/<project-name>.git (fetch)
    origin  git@github.com:<name>/<project-name>.git (push)
    

    上面显示了可以抓取和推送的origin的地址。如果没有推送权限,就看不到push的地址。

    A小伙伴:

    git clone ......
    

    克隆下来的项目只能看见master分支

    git branch 
    * master
    

    现在,你的小伙伴要在dev分支上开发,就必须创建远程origin的dev分支到本地,于是他用这个命令创建本地dev分支:

    git checkout -b dev origin/dev
    

    A小伙伴就可在dev分支上进行修改等等,比如

    git add .
    git commit -m ''
    git push origin master
    

    就在此时,我要对同一个地方进行了修改,并且要提交

    git add hello.py
    git commit -m 'add python'
    git push origin dev
    

    会发现推送失败了;因为你的小伙伴的最新提交和你试图推送的提交有冲突,解决办法也很简单,Git已经提示我们,先用git pull把最新的提交从origin/dev抓下来,然后,在本地合并,解决冲突,再推送:

    git pull
    remote: Counting objects: 5, done.
    remote: Compressing objects: 100% (2/2), done.
    remote: Total 3 (delta 0), reused 3 (delta 0)
    Unpacking objects: 100% (3/3), done.
    From github.com:michaelliao/learngit
    fc38031..291bea8  dev        -> origin/dev
    There is no tracking information for the current branch.
    Please specify which branch you want to merge with.
    See git-pull(1) for details
    
    git pull <remote> <branch>
    
    If you wish to set tracking information for this branch you can do so with:
    
    git branch --set-upstream dev origin/<branch>
    

    还是失败了,原因是没有指定本地dev分支与远程origin/dev分支的链接,根据提示,设置dev和origin/dev的链接

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

    这回git pull成功,但是合并有冲突,需要手动解决,解决的方法和分支管理中的解决冲突完全一样。解决后,提交,再push:

    $ git commit -m "merge & fix hello.py"
    [dev adca45d] merge & fix hello.py
    $ git push origin dev
    Counting objects: 10, done.
    Delta compression using up to 4 threads.
    Compressing objects: 100% (5/5), done.
    Writing objects: 100% (6/6), 747 bytes, done.
    Total 6 (delta 0), reused 0 (delta 0)
    To git@github.com:michaelliao/learngit.git
    291bea8..adca45d  dev -> dev
    
    • 忽略文件

    有些时候,你必须把某些文件放到Git工作目录中,但又不能提交它们,比如保存了数据库密码的配置文件啦,等等,每次git status都会显示Untracked files ...,有强迫症的童鞋心里肯定不爽。

    好在Git考虑到了大家的感受,这个问题解决起来也很简单,在Git工作区的根目录下创建一个特殊的.gitignore文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件。

    不需要从头写.gitignore文件,GitHub已经为我们准备了各种配置文件,只需要组合一下就可以使用了。所有配置文件可以直接在线浏览:https://github.com/github/gitignore

    忽略文件的原则是:

    忽略操作系统自动生成的文件,比如缩略图等;
    忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的.class文件;
    忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。
    举个例子:

    假设你在Windows下进行Python开发,Windows会自动在有图片的目录下生成隐藏的缩略图文件,如果有自定义目录,目录下就会有Desktop.ini文件,因此你需要忽略Windows自动生成的垃圾文件:

    Windows:

    Thumbs.db
    ehthumbs.db
    Desktop.ini
    然后,继续忽略Python编译产生的.pyc、.pyo、dist等文件或目录:

    Python:

    *.py[cod]
    *.so
    *.egg
    *.egg-info
    dist
    build
    

    加上你自己定义的文件,最终得到一个完整的.gitignore文件,内容如下:

    Windows:

    Thumbs.db
    ehthumbs.db
    Desktop.ini
    

    Python:

    *.py[cod]
    *.so
    *.egg
    *.egg-info
    dist
    build
    

    My configurations:

    db.ini
    deploy_key_rsa
    

    最后一步就是把.gitignore也提交到Git,就完成了!当然检验.gitignore的标准是git status命令是不是说working directory clean。

    使用Windows的童鞋注意了,如果你在资源管理器里新建一个.gitignore文件,它会非常弱智地提示你必须输入文件名,但是在文本编辑器里“保存”或者“另存为”就可以把文件保存为.gitignore了。

    有些时候,你想添加一个文件到Git,但发现添加不了,原因是这个文件被.gitignore忽略了:

    $ git add App.class
    The following paths are ignored by one of your .gitignore files:
    App.class
    Use -f if you really want to add them.
    

    如果你确实想添加该文件,可以用-f强制添加到Git:

    $ git add -f App.class
    

    或者你发现,可能是.gitignore写得有问题,需要找出来到底哪个规则写错了,可以用git check-ignore命令检查:

    $ git check-ignore -v App.class
    .gitignore:3:*.class    App.class
    

    Git会告诉我们,.gitignore的第3行规则忽略了该文件,于是我们就可以知道应该修订哪个规则。

    小结

    忽略某些文件时,需要编写.gitignore;
    .gitignore文件本身要放到版本库里,并且可以对.gitignore做版本管理!

    • 配置别名

    有没有经常敲错命令?比如git status?status这个单词真心不好记。

    如果敲git st就表示git status那就简单多了,当然这种偷懒的办法我们是极力赞成的。

    我们只需要敲一行命令,告诉Git,以后st就表示status:

    $ git config --global alias.st status
    

    好了,现在敲git st看看效果。

    当然还有别的命令可以简写,很多人都用co表示checkout,ci表示commit,br表示branch:

    $ git config --global alias.co checkout
    $ git config --global alias.ci commit
    $ git config --global alias.br branch
    

    以后提交就可以简写成:

    $ git ci -m "bala bala bala..."
    

    --global参数是全局参数,也就是这些命令在这台电脑的所有Git仓库下都有用。

    在撤销修改一节中,我们知道,命令git reset HEAD file可以把暂存区的修改撤销掉(unstage),重新放回工作区。既然是一个unstage操作,就可以配置一个unstage别名:

    $ git config --global alias.unstage 'reset HEAD'
    

    当你敲入命令:

    $ git unstage test.py
    

    实际上Git执行的是:

    $ git reset HEAD test.py
    

    配置一个git last,让其显示最后一次提交信息:

    $ git config --global alias.last 'log -1'
    

    这样,用git last就能显示最近一次的提交:

    $ git last
    commit adca45d317e6d8a4b23f9811c3d7b7f0f180bfe2
    Merge: bd6ae48 291bea8
    Author: Michael Liao <askxuefeng@gmail.com>
    Date:   Thu Aug 22 22:49:22 2013 +0800
    
    merge & fix hello.py
    

    甚至还有人丧心病狂地把lg配置成了:

    git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
    

    来看看git lg的效果:

    git-lg

    image.png

    为什么不早点告诉我?别激动,咱不是为了多记几个英文单词嘛!

    配置文件
    配置Git的时候,加上--global是针对当前用户起作用的,如果不加,那只针对当前的仓库起作用。

    配置文件放哪了?每个仓库的Git配置文件都放在.git/config文件中:

    $ cat .git/config 
    [core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
        ignorecase = true
        precomposeunicode = true
    [remote "origin"]
        url = git@github.com:michaelliao/learngit.git
        fetch = +refs/heads/*:refs/remotes/origin/*
    [branch "master"]
        remote = origin
        merge = refs/heads/master
    [alias]
        last = log -1
    

    别名就在[alias]后面,要删除别名,直接把对应的行删掉即可。

    而当前用户的Git配置文件放在用户主目录下的一个隐藏文件.gitconfig中:

    
    $ cat .gitconfig
    [alias]
        co = checkout
        ci = commit
        br = branch
        st = status
    [user]
        name = Your Name
        email = your@email.com
    

    配置别名也可以直接修改这个文件,如果改错了,可以删掉文件重新通过命令配置。

    refusing to merge unrelated histories
    

    解决方法

    git pull --allow-unrelated-histories
    

    通过廖雪峰老师的git教程,又重新学习了一遍

    相关文章

      网友评论

          本文标题:Git 复习重新开始

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