Git学习小记

俗话说好记性不如烂笔头,此篇用来记一下常用的命令和一些操作,以后碰到啥问题也都放上来,前面的是跟着廖雪峰的教程过的。

我的mac和阿里云服务器都带git,所以安装啥的就不说了git官网地址:https://git-scm.com/ 各位可以自己去看一下。

创建一个本地仓库

  • 创建一个版本库:首先选择一个合适的地方,创建一个空目录:
$ mkdir studygit

然后进入这个目录并通过git init命令把这个目录变成git可以管理的仓库:

$ cd studygit
$ git init
Initialized empty Git repository in...
  • 添加文件到仓库
    首先新建一个文件并添加文字内容:
$ touch helloworld
// 我这是mac,各位根据自己的系统考虑要不要这个
$ vi helloworld

添加文字”hello world!”然后保存。将文件添加到git仓库:

$ git add helloworld
// $ git add .    提交所有修改文件不包括删除的文件

然后用git commit告诉git,把文件提交到仓库。

$ git commit helloworld -m "init"

-m后面的是本次提交的说明

版本控制相关

接着上面的来,现在修改helloworld中的内容,增加一行文字hello git

《Git学习小记》 Hello Git

  • 使用git status查看状态:
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   helloworld

no changes added to commit (use "git add" and/or "git commit -a")
  • 使用 git diff对比文件:
$ git diff hello world
diff --git a/helloworld b/helloworld
index a042389..aaf0674 100644
--- a/helloworld
+++ b/helloworld
@@ -1 +1,2 @@
 hello world!
+hello git!

接着add 和 commit 与之前的一样,不再赘述。

  • 查看历史记录:git log
$ git log
commit 03c3d76e1f6b405af5ca9d9c2268b1ff120d601e
Author: xiasuhuei321 <xiasuhuei321@163.com>
Date:   Fri Jan 20 13:35:25 2017 +0800

    add some words

commit 13cc7cae5312cdcb3149c1caa554c2dbb3540e49
Author: xiasuhuei321 <xiasuhuei321@163.com>
Date:   Fri Jan 20 12:59:29 2017 +0800

    init
  • 将helloworld回退回上个版本:
    在git中,用HEAD表示当前版本,上个版本就是HEAD,上上个HEAD^,100个版本前,HEAD~100
$ git reset --hard HEAD^
HEAD is now at 13cc7ca init

《Git学习小记》 回退

这个时候虽然回退到了上个版本,但是git log也看不到上一次的提交记录了,不过如果你记得上次提交的版本号,依然是可以恢复的。

  • 回到回退之前的版本:
$ git reset --hard 03c3d76e1f6b405af5ca9d9c2268b1ff120d601e
HEAD is now at 03c3d76 add some words

《Git学习小记》 再恢复

  • 查看commit id:
$ git reflog
03c3d76 HEAD@{0}: reset: moving to 03c3d76e1f6b405af5ca9d9c2268b1ff120d601e
13cc7ca HEAD@{1}: reset: moving to HEAD^
03c3d76 HEAD@{2}: commit: add some words
13cc7ca HEAD@{3}: commit (initial): init

恩,事实上我上面写那么长的id根本没有必要,不过就吓吓自己,不要瞎动东西。。。

  • 撤销修改
    在helloworld中新增一行:a ha?

《Git学习小记》 a ha?

$ git checkout -- helloworld

《Git学习小记》 a ha?

上面是没有使用git add命令的撤回修改,使用了该命令的撤销修改:

$ git reset HEAD helloworld
Unstaged changes after reset:
M   helloworld

此时已经把暂存区的修改回退到工作区,接着和上面一样,丢弃工作区的修改。

$ git checkout -- helloworld
  • 删除文件
    在git仓库中新建一个文件并提交,接着使用rm命令删除,这时使用git status命令查看:
$ git status
On branch master
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    deleted:    test

no changes added to commit (use "git add" and/or "git commit -a")

如果确实要从版本库中删除该文件,使用git rm删掉,并且commit:

$ git rm test
rm 'test'

$ git commit -m "remove test.txt"
[master c8a961c] remove test.txt
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 test

如果是删错了,恢复:

git checkout -- test

远程仓库

双十一的时候买了一台阿里云服务器,就用这个折腾一下吧。

首先还是一样的,创建一个studygit目录。

# mkdir studygit

《Git学习小记》 创建文件夹

然后初始化

# git init

创建一个hello文件,并写入hello字符

# vi hello 

将hello加入git仓库

# git add hello
# git commit -m "init"

之后再我自己的终端使用clone命令

$ git clone git@xxx:/studygit/.git
Cloning into 'studygit'...
git@xxx's password: 
Could not chdir to home directory /home/git: No such file or directory
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (3/3), done.

其中xxx是服务器ip,我现在比较菜= =不知道能不能暴露,先不写上来了
使用ls命令看看有没有clone下来:

$ ls
helloworld  studygit

进入该studygit,也就是clone下来的仓库查看hello文件是否有hello字符

$ cd studygit
$ vi hello

《Git学习小记》 hello

clone问题不大,在push的时候我碰到了一些问题,由于我现在不是非常的懂Linux,所以暂时不详细的讲,只把现象和我暂时找到的解决方法写上来。

$ git push git@xxx:studygit/.git
Could not chdir to home directory /home/git: No such file or directory
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 253 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
error: insufficient permission for adding an object to repository database ./objects

主要是因为权限问题,我不是很了解Linux中的权限和git权限之类的,暂时先放着,只放上我看到的其中一个我试了可以,而且比较简单的方法和他的解释:
这是因为git服务器端对应git仓库目录的访问权限问题,如果一定要多用户访问git仓库,可以设置一个gituser组,给他分配足够的权限即可。

# chgrp -R gituser path/to/gitrepo
# chmod -R 'g+rwx' /path/to/gitrepo
或者直接
# chmod 777 /path/to/gitrepo -R

第三个大概是要root权限的,777好像是简单粗暴了点,不过我现在不是非常的了解。

继续push还是会错:

Could not chdir to home directory /home/git: No such file or directory
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 253 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require 'git reset --hard' to match
remote: error: the work tree to HEAD.
remote: error: 
remote: error: You can set 'receive.denyCurrentBranch' configuration variable t
remote: error: 'ignore' or 'warn' in the remote repository to allow pushing int
remote: error: its current branch; however, this is not recommended unless you
remote: error: arranged to update its work tree to match what you pushed in som
remote: error: other way.
remote: error: 
remote: error: To squelch this message and still keep the default behaviour, se
remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.

因为我们使用git init初始化的远程仓库,默认情况下git是拒绝push操作的,需要修改配置在git服务器端对应的git仓库的配置文件。在.git/config文件中增加如下配置:

[receive]
            denyCurrentBranch = ignore

《Git学习小记》 增加配置

最终终于push成功了!

Could not chdir to home directory /home/git: No such file or directory
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 253 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To 112.74.43.104:studygit/.git
   7e39b28..bac4117  master -> master

多人合作

新建dev分支

$ git branch dev

切换到dev分支

$ git checkout  dev

查看远程仓库

$ git remote -v

查看远程分支

$ git branch -a

将本地分支push到远程分支

$git push origin local_branch:remote_branch

这个操作,local_branch必须为你本地存在的分支,remote_branch为远程分支,如果remote_branch不存在则会自动创建分支。
类似,git push origin :remote_branch,local_branch留空的话则是删除远程remote_branch分支。

取回远程主机某个分支的更新,与本地的指定分支合并

$ git pull <远程主机名> <远程分支名>:<本地分支名>

删除远程分支:

$ git push origin --delete <branchName>

删除tag:

git push origin --delete tag <tagname>

合并commit,在各种情况下,我们都有可能在代码没有完全完成的情况下提交commit,可以利用rebase命令合并commit:

$ git rebase -i commitid

commitid是最新一次commit的id

杂记

git配置用户名和邮箱:

$ git config --global user.name [your name]
$ git config --global user.email [your email]

查看远程仓库

$ git remote -v

记一次从暂存恢复代码的经历

一天上班的时候用git stash暂存了代码,后来有事出去了,第二天来的时候代码都没了,哇,真的绝望,因为重写一遍怪麻烦的。当然了,转念一想,我用git应该会有恢复的办法,上网搜了一下,果然有。首先用git stash list看一下历史

$ git stash list

《Git学习小记》 stash list

前面的0、1啥的表示下标,看到这个,就感觉稳了,恢复有望。
后来用了如下的命令恢复了代码:

$ git stash pop --index

–index表示不仅恢复工作区,还恢复暂存区,后面可以跟参数恢复指定的记录。我这里没有指明默认恢复最新记录。

小记:最近切换分支,切换回来的时候发现stash的内容没了,那这可能就是他工作的方式,不同于commit,stash就是需要我们自己选择一个恢复过来。可以用如下命令:

$ git stash apply stash@{1}
点赞