1) 如果已经创建过远程代码库:
Quick setup — if you’ve done this kind of thing before
or(HTTPS|SSH) git clone [email protected]:jiucang/test.git
We recommend every repository include a README, LICENSE, and .gitignore.
…or create a new repository on the command line
2) 如果没有创建远程代码库:
echo "# test" >> README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin git@github.com:jiucang/test.git
git push -u origin master
…or push an existing repository from the command line
执行以上代码则会创建远程代码库,当前目录为本地代码库
3) 如果有一个已知的本地代码库,上传到服务器上,只需要执行以下操作即可:
git remote add origin git@github.com:jiucang/test.git
git push -u origin master
…or import code from another repository
You can initialize this repository with code from a Subversion, Mercurial, or TFS project.
Import code
有了本地代码库之后,不建议直接对本地代码库进行修改;有了第一次commit之后,会找到master的branch!建议先创建自己工作需要的分支,然后在该分支上面进行代码修改,修改之后commit;切换到master branch,然后将改动merge到master branch. 最后push到remote的代码库中。
首先介绍一下本地代码库的几个组成部分:
参考:http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/0013745374151782eb658c5a5ca454eaa451661275886c6000
提交代码时:
1) git add: 把文件添加到版本库的stage,暂存区中
2) git commit: 提交更改,将暂存区的内容添加到了当前分支中,这里是master分支
git add xxx
git commit -m "yyy"
git push -u origin master
如果不是在master分支上进行的操作,而是在work_branch上进行的操作:
work_branch:
git add xxx
git commit -m "yyy"
git checkout master 切换到master branch
master:
git merge work_branch git merge 操作会合并到当前分支,这里当前分支为master,所以会合并到master分支上
git push -u origin master
修改文件xxx,git add 之后如何回退:
1) 直接丢弃xxx的修改
使用git checkout - - xxx;
注意这里的- -的作用非常重要,不然的话,就会直接被视为是branch切换的操作了。这里的实现原理是,使用版本库的分支上的文件xxx来替换该文件xxx。
2) 不丢弃xxx的修改,只是将xxx还原到在使用git add之前的状态即可。
使用:git reset xxx
3) 同理如果一下git add *,添加了好多文件,如何一下子去除呢,
使用git reset .
git commit -m “yyy”:即修改了一个文件xxx,还git add, git commit到了最终的本地版本库分支上了,如何回退:
问题来了,考虑以下需求,
1) 丢弃文件,直接回到上一个版本:
使用git reset - -hard HEAD^ 即可
2) 如果忘记git add了某一个文件xxx2,但是不想重新再commit一个新的tag记录?或者提交信息写错了?
gitcommit−m‘initialcommit′ git add forgotten_file
$ git commit –amend last_commit_id
git commit –amend命令可以修改commit id,所以这里可以先添加xxx2文件,然后修改一下commit即可
3) 如果发现有很多文件都要修改,想直接回到git add之前的状态,又不想reset之后丢失数据?
以下为一种方法的实例,git reset - -soft + git reset modified_file:顺便介绍一下git reset –soft|–hard|–mixed HEAD^区别
➜ ubuntu_using_guide git:(master) ✗ echo "hello" > test.txt
➜ ubuntu_using_guide git:(master) ✗ git add test.txt
➜ ubuntu_using_guide git:(master) ✗ git commit -m "just say hello"
[master 848defc] just say hello
1 file changed, 1 insertion(+)
create mode 100644 test.txt
➜ ubuntu_using_guide git:(master) ✗ git log --pretty=oneline
848defcf5f31ee88efa673f4876e8e9fc7c466ed just say hello
ec859ad3ae54072d9840cad3bab981cf81abdcab samba share environment prepare
(END)
➜ ubuntu_using_guide git:(master) ✗ git reset --soft HEAD^
➜ ubuntu_using_guide git:(master) ✗ git status
位于分支 master
您的分支与上游分支 'origin/master' 一致。
要提交的变更:
(使用 "git reset HEAD ..." 撤出暂存区)
新文件: test.txt
➜ ubuntu_using_guide git:(master) ✗ cat test.txt
hello
➜ ubuntu_using_guide git:(master) ✗ git log --pretty=oneline
ec859ad3ae54072d9840cad3bab981cf81abdcab samba share environment prepare
(END)
发现test.txt还是在stage的区域,切修改还是存在的,但是git log 时发现HEAD指针已经指向了前一个commit,即现在的commit id。
➜ ubuntu_using_guide git:(master) ✗ git reset test.txt
➜ ubuntu_using_guide git:(master) ✗ git status
位于分支 master
您的分支与上游分支 'origin/master' 一致。
提交为空,但是存在尚未跟踪的文件(使用 "git add" 建立跟踪)
➜ ubuntu_using_guide git:(master) ✗ cat test.txt
hello
同样是以上文件test.txt,内容修改为hello world! 使用git reset --hard操作
➜ ubuntu_using_guide git:(master) ✗ cat test.txt
hello world!
➜ ubuntu_using_guide git:(master) ✗ git status
位于分支 master
您的分支与上游分支 'origin/master' 一致。
未跟踪的文件:
(使用 "git add ..." 以包含要提交的内容)
test.txt
提交为空,但是存在尚未跟踪的文件(使用 "git add" 建立跟踪)
➜ ubuntu_using_guide git:(master) ✗ git log --pretty=oneline
ec859ad3ae54072d9840cad3bab981cf81abdcab samba share environment prepare
(END)
➜ ubuntu_using_guide git:(master) ✗ git add test.txt
➜ ubuntu_using_guide git:(master) ✗ git commit -m "just say hello world"
[master e2ec086] just say hello world
1 file changed, 1 insertion(+)
create mode 100644 test.txt
➜ ubuntu_using_guide git:(master) ✗ git log --pretty=oneline
e2ec0865e412ca97a5d74f9bc3fc6cbba2540bdf just say hello world
ec859ad3ae54072d9840cad3bab981cf81abdcab samba share environment prepare
(END)
如果这里直接使用git reset test.txt; git status; git log 发现没有任何作用?说明git reset file 只能完成unstage(可以视为git add的逆操作),现在试试git reset --hard HEAD^
➜ ubuntu_using_guide git:(master) ✗ git reset --hard HEAD^
HEAD 现在位于 ec859ad samba share environment prepare
➜ ubuntu_using_guide git:(master) ✗ cat test.txt
cat: test.txt: 没有那个文件或目录
直接文件就没有了,悲剧,彻底会到了之前的版本,所有修改都都丢失了!
参考:http://stackoverflow.com/questions/3528245/whats-the-difference-between-git-reset-mixed-soft-and-hard
When you modify a file in your repository, the change is initially unstaged. In order to commit it, you must stage it—that is, add it to the index—using git add. When you make a commit, the changes that are committed are those that have been added to the index.
git reset changes, at minimum, where the current branch (HEAD) is pointing. The difference between --mixed and --soft is whether or not your index is also modified. So, if we're on branch master with this series of commits:
- A - B - C (master)
HEADpoints to C and the index matches C.
When we run git reset --soft B, master (and thus HEAD) now points to B, but the index still has the changes from C; git status will show them as staged. So if we run git commit at this point, we'll get a new commit with the same changes as C.
Okay, so starting from here again:
- A - B - C (master)
Now let's do git reset --mixed B. Once again, master and HEAD point to B, but this time the index is also modified to match B. If we run git commit at this point, nothing will happen since the index matches HEAD. We still have the changes in the working directory, but since they're not in the index, git status shows them as unstaged. To commit them, you would git add and then commit as usual.
And finally, --hard is the same as --mixed (it changes your HEAD and index), except that --hard also modifies your working directory. If we're at C and run git reset --hard B, then the changes added in C, as well as any uncommitted changes you have, will be removed, and the files in your working copy will match commit B. Since you can permanently lose changes this way, you should always run git status before doing a hard reset to make sure your working directory is clean or that you're okay with losing your uncommitted changes.
git rm 到底有啥用?
参考:https://git-scm.com/docs/git-rm
git rm - Remove files from the working tree and from the index
显而易见,这里说git rm的作用就是删除工作区的文件而已!
考虑一种情况:如果使用rm 删除了一个文件,如果使用git add添加进去?
好吧,好像无法使用git add的操作来添加,可以使用:git add -A的方法来实现,即添加所有有修改过的文件
另一种方法,使用:git commit -a, 添加commit,添加对应的修改项(去除文件中的#)
git checkout [-b] branch: 分支创建和切换
git checkout -b new branch—name:
创建一个新的branch,使用命令
$ git checkout -b new v2.6.13
git checkout: 切换到新的branch
一开始使用git branch --all命令查看,发现自己新创建的分支没有找到,这里需要先同步一下代码, 使用 :git fetch origin;
我以前一般切换到某个分支,如development,则使用:git fetch origin development 或git pull origin development,这样只能同步对应的分支。
如果需要更新所有的分支信息,则直接使用:git fetch origin 或 git pull origin即可
root@MRCAndroid07:/home/project/kernel# git fetch origin
remote: Counting objects: 15, done.remote: Compressing objects: 100% (8/8), done.remote: Total 8 (delta 7), reused 0 (delta 0)Unpacking objects: 100% (8/8), done.From ssh://nsrd/project/kernel/omap
* [new branch] bac -> origin/bac //找到了新的branch
root@MRCAndroid07:/home/project/kernel# git branch --all //列出所有的分支* master remotes/origin/abc
remotes/origin/working
root@MRCAndroid07:/home/project/kernel# git branch //当前使用的分支* master root@MRCAndroid07:/home/project/kernel#git checkout abc // 这里就切换到了对应的abc 分支了,呵呵Checking out files: 100% (39411/39411), done.Branch abc set up to track remote branchabc from origin.
Switched to a new branch 'abc'
同时我也想有个更好的方案来应对切换分支时未保存的修改的问题..
存多个可以添加备注信息。
git stash save "message"
stash list 里面也有branch信息
git stash list
stash@{0}: On branch2: message2
stash@{1}: On branch1: message1
恢复就选择想要的就可以了。
git stash pop stash@{1} 在不同分支切换stash应该是最好的方案了。
特殊问题:
1)git stash 后发现stash的东西不见了,可以试试先git stash; git stash apply;
2) git stash pop xxx 发现出现了冲突,如何解决!
参考后续更新的博客!