Git-Git基本操作
先来合个影
马上就要和之前实践遗留的数据告别了,告别之前是不是要留个影呢?在Git里,“留影”用的命令叫做tag,更加专业的术语叫做“里程碑”(打tag,或打标签)。
$ cd /path/to/my/workspace/demo
$ git tag -m "Say bye-bye to all previous practice." old_practice
通过记录提交ID(或者创建Tag对象)来为当前版本库状态进行“留影”。
$ ls .git/refs/tags/old_practice
.git/refs/tags/old_practice
$ git rev-parse refs/tags/old_practice
41bd4e2cce0f8baa9bb4cdda62927b408c846cd6
留过影之后,可以执行git describe命令显示当前版本库的最新提交的版本号。显示的时候会选取离该提交最近的里程碑作为“基础版本号”,后面附加标识距离“基础版本”的数字以及该提交的SHA1哈希值缩写。因为最新的提交上恰好被打了一个“里程碑”,所以用“里程碑”的名字显示为版本号。这个技术在后面的示例代码中被使用。
$ git describe
old_practice
删除文件
看看版本库当前的状态,暂存区和工作区都包含修改。
$ git status -s
A hack-1.txt
M welcome.txt
在这个暂存区和工作区都包含文件修改的情况下,使用删除命令更具有挑战性。删除命令有多种使用方法,有的方法很巧妙,而有的方法需要更多的输入。为了分别介绍不同的删除方法,还要使用上一章介绍的进度保存(git-stash)命令。
- 保存进度。
$ git stash
Saved working directory and index state WIP on master: 2b31c19 Merge commit 'acc2f69'
HEAD is now at 2b31c19 Merge commit 'acc2f69'
- 再恢复进度。注意不要使用git stash pop,而是使用git stash apply,因为这个保存的进度要被多次用到。
$ git stash apply
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: hack-1.txt
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: welcome.txt
#
本地删除不是真的删除
当前工作区的文件有:
$ ls
detached-commit.txt
hack-1.txt
new-commit.txt
welcome.txt
直接在工作区删除这些文件,会如何呢?
$ rm *.txt
通过下面的命令,可以看到在暂存区(版本库)中文件仍在,并未删除。
$ git ls-files
detached-commit.txt
hack-1.txt
new-commit.txt
welcome.txt
通过文件的状态来看,文件只是在本地进行了删除,尚未加到暂存区(提交任务)中。也就是说:直接在工作区删除,对暂存区和版本库没有任何影响。
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: hack-1.txt
#
# Changed but not updated:
# (use "git add/rm <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# deleted: detached-commit.txt
# deleted: hack-1.txt
# deleted: new-commit.txt
# deleted: welcome.txt
#
从Git状态输出可以看出,本地删除如果要反映在暂存区中应该用git rm命令,对于不想删除的文件执行git checkout – 可以让文件在工作区重现。
执行git rm命令删除文件
按照上面状态输出的内容,将所有的文本文件删除。执行下面的命令。
$ git rm detached-commit.txt hack-1.txt new-commit.txt welcome.txt
rm 'detached-commit.txt'
rm 'hack-1.txt'
rm 'new-commit.txt'
rm 'welcome.txt'
再看一看状态:
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# deleted: detached-commit.txt
# deleted: new-commit.txt
# deleted: welcome.txt
#
删除动作加入了暂存区。这时执行提交动作,就真正意义上执行了文件删除。
$ git commit -m "delete trash files. (using: git rm)"
[master 483493a] delete trash files. (using: git rm)
1 files changed, 0 insertions(+), 2 deletions(-)
delete mode 100644 detached-commit.txt
delete mode 100644 new-commit.txt
delete mode 100644 welcome.txt
不过不要担心,文件只是在版本库最新提交中删除了,在历史提交中尚在。可以通过下面命令查看历史版本的文件列表。
$ git ls-files --with-tree=HEAD^
detached-commit.txt
new-commit.txt
welcome.txt
也可以查看在历史版本中尚在的删除文件的内容。
$ git cat-file -p HEAD^:welcome.txt
Hello.
Nice to meet you.
命令git add -u快速标记删除
在前面执行git rm命令时,一一写下了所有要删除的文件名,好长的命令啊!能不能简化些?实际上git add可以,即使用-u参数调用git add命令,含义是将本地有改动(包括添加和删除)的文件标记为删除。为了重现刚才的场景,先使用重置命令抛弃最新的提交,再使用进度恢复到之前的状态。
- 丢弃之前测试删除的试验性提交。
$ git reset --hard HEAD^
HEAD is now at 2b31c19 Merge commit 'acc2f69'
- 恢复保存的进度。(参数-q使得命令进入安静模式)
$ git stash apply -q
然后删除本地文件,状态依然显示只在本地删除了文件,暂存区文件仍在。
$ rm *.txt
$ git status -s
D detached-commit.txt
AD hack-1.txt
D new-commit.txt
D welcome.txt
执行git add -u命令可以将(被版本库追踪的)本地文件的变更(修改、删除)全部记录到暂存区中。
$ git add -u
查看状态,可以看到工作区删除的文件全部被标记为下次提交时删除。
$ git status -s
D detached-commit.txt
D new-commit.txt
D welcome.txt
执行提交,删除文件。
$ git commit -m "delete trash files. (using: git add -u)"
[master 7161977] delete trash files. (using: git add -u)
1 files changed, 0 insertions(+), 2 deletions(-)
delete mode 100644 detached-commit.txt
delete mode 100644 new-commit.txt
delete mode 100644 welcome.txt
恢复删除的文件
经过了上面的文件删除,工作区已经没有文件了。为了说明文件移动,现在恢复一个删除的文件。前面已经说过执行了文件删除并提交,只是在最新的提交中删除了文件,历史提交中文件仍然保留,可以从历史提交中提取文件。执行下面的命令可以从历史(前一次提交)中恢复welcome.txt文件。
$ git cat-file -p HEAD~1:welcome.txt > welcome.txt
上面命令中出现的HEAD~1即相当于HEAD^都指的是HEAD的上一次提交。执行git add -A命令会对工作区中所有改动以及新增文件添加到暂存区,也是一个常用的技巧。执行下面的命令后,将恢复过来的welcome.txt文件添加回暂存区。
$ git add -A
$ git status -s
A welcome.txt
执行提交操作,文件welcome.txt又回来了。
$ git commit -m "restore file: welcome.txt"
[master 63992f0] restore file: welcome.txt
1 files changed, 2 insertions(+), 0 deletions(-)
create mode 100644 welcome.txt
通过再次添加的方式恢复被删除的文件是最自然的恢复的方法。其他版本控制系统如CVS也采用同样的方法恢复删除的文件,但是有的版本控制系统如Subversion如果这样操作会有严重的副作用——文件变更历史被人为的割裂而且还会造成服务器存储空间的浪费。Git通过添加方式反删除文件没有副作用,这是因为在Git的版本库中相同内容的文件保存在一个blob对象中,而且即便是内容不同的blob对象在对象库打包整理过程中也会通过差异比较优化存储。
移动文件
通过将welcome.txt改名为README文件来测试一下在Git中如何移动文件。Git提供了git mv命令完成改名操作。
$ git mv welcome.txt README
可以从当前的状态中看到改名的操作。
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# renamed: welcome.txt -> README
#
提交改名操作,在提交输出可以看到改名前后两个文件的相似度(百分比)。
$ git commit -m "改名测试"
[master 7aa5ac1] 改名测试
1 files changed, 0 insertions(+), 0 deletions(-)
rename welcome.txt => README (100%)
从提交日志中出现的文件相似度可以看出Git的改名实际上源自于Git对文件追踪的强大支持(文件内容作为blob对象保存在对象库中)。改名操作实际上相当于对旧文件执行删除,对新文件执行添加,即完全可以不使用git mv操作,而是代之以git rm和一个git add操作。为了试验不使用git mv命令是否可行,先撤销之前进行的提交。
- 撤销之前测试文件移动的提交。
$ git reset --hard HEAD^
HEAD is now at 63992f0 restore file: welcome.txt
- 撤销之后welcome.txt文件又回来了。
$ git status -s
$ git ls-files
welcome.txt
新的改名操作不使用git mv命令,而是直接在本地改名(文件移动),将welcome.txt 改名为README。
$ mv welcome.txt README
$ git status -s
D welcome.txt
?? README
为了考验一下Git的内容追踪能力,再修改一下改名后的 README 文件,即在文件末尾追加一行。
$ echo "Bye-Bye." >> README
可以使用前面介绍的git add -A命令。相当于对修改文件执行git add,对删除文件执行git rm,而且对本地新增文件也执行git add。
$ git add -A
查看状态,也可以看到文件重命名。
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# renamed: welcome.txt -> README
#
执行提交。
$ git commit -m "README is from welcome.txt."
[master c024f34] README is from welcome.txt.
1 files changed, 1 insertions(+), 0 deletions(-)
rename welcome.txt => README (73%)
这次提交中也看到了重命名操作,但是重命名相似度不是 100%,而是 73%。
一个显示版本号的Hello World
在一开始为纪念前面的实践留了一个影,叫做old_practice。现在再次执行git describe看一下现在的版本号。
$ git describe
old_practice-3-gc024f34
就是说:当前工作区的版本是“留影”后的第三个版本,提交ID是c024f34。
下面的命令可以在提交日志中显示提交对应的里程碑(Tag)。其中参数--decorate可以在提交ID的旁边显示该提交关联的引用(里程碑或分支)。
$ git log --oneline --decorate -4
c024f34 (HEAD, master) README is from welcome.txt.
63992f0 restore file: welcome.txt
7161977 delete trash files. (using: git add -u)
2b31c19 (tag: old_practice) Merge commit 'acc2f69'
命令git describe的输出可以作为软件版本号,这个功能非常有用。因为这样可以很容易的实现将发布的软件包版本和版本库中的代码对应在一起,当发现软件包包含Bug时,可以最快、最准确的对应到代码上。
下面的Hello World程序就实现了这个功能。创建目录src,并在src目录下创建下面的三个文件:
- 文件:src/main.c
没错,下面的几行就是这个程序的主代码,和输出相关代码的就两行,一行显示“Hello, world.”,另外一行显示软件版本。在显示软件版本时用到了宏_VERSION,这个宏的来源参考下一个文件。
源代码:
#include "version.h"
#include <stdio.h>
int
main()
{
printf( "Hello, world.\n" );
printf( "version: %s.\n", _VERSION );
return 0;
}
- 文件:src/version.h.in
没错,这个文件名的后缀是.h.in。这个文件其实是用于生成文件version.h的模板文件。在由此模板文件生成的version.h的过程中,宏_VERSION的值 “” 会动态替换。
源代码:
#ifndef HELLO_WORLD_VERSION_H
#define HELLO_WORLD_VERSION_H
#define _VERSION "<version>"
#endif
- 文件:src/Makefile
这个文件看起来很复杂,而且要注意所有缩进都是使用一个<Tab>键完成的缩进,千万不要错误的写成空格,因为这是Makefile。这个文件除了定义如何由代码生成可执行文件hello之外,还定义了如何将模板文件version.h.in转换为version.h。在转换过程中用git describe命令的输出替换模板文件中的<version>字符串。
源代码:
OBJECTS = main.o
TARGET = hello
all: $(TARGET)
$(TARGET): $(OBJECTS)
$(CC) -o $@ $^
main.o: | new_header
main.o: version.h
new_header:
@sed -e "s/<version>/$$(git describe)/g" \
< version.h.in > version.h.tmp
@if diff -q version.h.tmp version.h >/dev/null 2>&1; \
then \
rm version.h.tmp; \
else \
echo "version.h.in => version.h" ; \
mv version.h.tmp version.h; \
fi
clean:
rm -f $(TARGET) $(OBJECTS) version.h
.PHONY: all clean
上述三个文件创建完毕之后,进入到src目录,试着运行一下。先执行make编译,再运行编译后的程序hello。
$ cd src
$ make
version.h.in => version.h
cc -c -o main.o main.c
cc -o hello main.o
$ ./hello
Hello, world.
version: old_practice-3-gc024f34.
使用git add -i选择性添加
刚刚创建的Hello World程序还没有添加到版本库中,在src目录下有下列文件:
$ cd /path/to/my/workspace/demo
$ ls src
hello main.c main.o Makefile version.h version.h.in
这些文件中hello,main.o和version.h都是在编译时生成的程序,不应该加入到版本库中。那么选择性添加文件除了针对文件逐一使用git add命令外,还有什么办法么?通过使用-i参数调用git add就是一个办法,提供了一个交互式的界面。
执行git add -i命令,进入一个交互式界面,首先显示的是工作区状态。显然因为版本库进行了清理,所以显得很“干净”。
$ git add -i
staged unstaged path
*** Commands ***
1: status 2: update 3: revert 4: add untracked
5: patch 6: diff 7: quit 8: help
What now>
在交互式界面显示了命令列表,可以使用数字或者加亮显示的命令首字母,选择相应的功能。对于此例需要将新文件加入到版本库,所以选择“4”。
What now> 4
1: src/Makefile
2: src/hello
3: src/main.c
4: src/main.o
5: src/version.h
6: src/version.h.in
Add untracked>>
当选择了“4”之后,就进入了“Add untracked”界面,显示了本地新增(尚不再版本库中)的文件列表,而且提示符也变了,由“What now>”变为“Add untracked>>”。依次输入1、3、6将源代码添加到版本库中。
- 输入“1”:
Add untracked>> 1
* 1: src/Makefile
2: src/hello
3: src/main.c
4: src/main.o
5: src/version.h
6: src/version.h.in
- 输入“3”:
Add untracked>> 3
* 1: src/Makefile
2: src/hello
* 3: src/main.c
4: src/main.o
5: src/version.h
6: src/version.h.in
- 输入“6”:
输入“6”:
Add untracked>> 6
* 1: src/Makefile
2: src/hello
* 3: src/main.c
4: src/main.o
5: src/version.h
* 6: src/version.h.in
Add untracked>>
每次输入文件序号,对应的文件前面都添加一个星号,代表将此文件添加到暂存区。在提示符“Add untracked>>”处按回车键,完成文件添加,返回主界面。
Add untracked>>
added 3 paths
*** Commands ***
1: status 2: update 3: revert 4: add untracked
5: patch 6: diff 7: quit 8: help
What now>
此时输入“1”查看状态,可以看到三个文件添加到暂存区中。
What now> 1
staged unstaged path
1: +20/-0 nothing src/Makefile
2: +10/-0 nothing src/main.c
3: +6/-0 nothing src/version.h.in
*** Commands ***
1: status 2: update 3: revert 4: add untracked
5: patch 6: diff 7: quit 8: help
输入“7”退出交互界面。
查看文件状态,可以发现三个文件被添加到暂存区中。
$ git status -s
A src/Makefile
A src/main.c
A src/version.h.in
?? src/hello
?? src/main.o
?? src/version.h
完成提交。
$ git commit -m "Hello world initialized."
[master d71ce92] Hello world initialized.
3 files changed, 36 insertions(+), 0 deletions(-)
create mode 100644 src/Makefile
create mode 100644 src/main.c
create mode 100644 src/version.h.in
Hello world引发的新问题
进入src目录中,对Hello world执行编译。
$ cd /path/to/my/workspace/demo/src
$ make clean && make
rm -f hello main.o version.h
version.h.in => version.h
cc -c -o main.o main.c
cc -o hello main.o
运行编译后的程序,是不是对版本输出不满意呢?
$ ./hello
Hello, world.
version: old_practice-4-gd71ce92
之所以显示长长的版本号,是因为使用了在本章最开始留的“影”。现在为Hello world留下一个新的“影”(一个新的里程碑)吧。
$ git tag -m "Set tag hello_1.0." hello_1.0
然后清除上次编译结果后,重新编译和运行,可以看到新的输出。
$ make clean && make
rm -f hello main.o version.h
version.h.in => version.h
cc -c -o main.o main.c
cc -o hello main.o
$ ./hello
Hello, world.
version: hello_1.0.
编译的目标文件和以及从模板生成的头文件出现在了Git的状态输出中,这些文件会对以后的工作造成干扰。当写了新的源代码文件需要添加到版本库中时,因为这些干扰文件的存在,不得不一一将这些干扰文件排除在外。更为严重的是,如果不小心执行git add .或者git add -A命令会将编译的目标文件及其他临时文件加入版本库中,浪费存储空间不说甚至还会造成冲突。
Git提供了文件忽略功能,可以解决这个问题。
文件忽略
Git提供了文件忽略功能。当对工作区某个目录或者某些文件设置了忽略后,再执行git status查看状态时,被忽略的文件即使存在也不会显示为未跟踪状态,甚至根本感觉不到这些文件的存在。现在就针对Hello world程序目录试验一下。
$ cd /path/to/my/workspace/demo/src
$ git status -s
?? hello
?? main.o
?? version.h
可以看到src目录下编译的目标文件等显示为未跟踪,每一行开头的两个问号好像在向我们请求:“快把我们添加到版本库里吧”。
执行下面的命令可以在这个目下创建一个名为.gitignore的文件(注意文件的前面有个点),把这些要忽略的文件写在其中,文件名可以使用通配符。注意:第2行到第5行开头的右尖括号是cat命令的提示符,不是输入。
$ cat > .gitignore << EOF
> hello
> *.o
> *.h
> EOF
看看写好的.gitignore文件。每个要忽略的文件显示在一行。
把.gitignore文件添加到版本库中吧。(如果不希望添加到库里,也不希望.gitignore文件带来干扰,可以在忽略文件中忽略自己。)
$ git add .gitignore
$ git commit -m "ignore object files."
[master b3af728] ignore object files.
1 files changed, 3 insertions(+), 0 deletions(-)
create mode 100644 src/.gitignore
file:.gitignore
文件可以放在任何目录
文件.gitignore的作用范围是其所处的目录及其子目录,因此如果把刚刚创建的.gitignore移动到上一层目录(仍位于工作区内)也应该有效。
$ git mv .gitignore ..
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# renamed: .gitignore -> ../.gitignore
#
果然移动.gitignore文件到上层目录,Hello world程序目录下的目标文件依然被忽略着。
提交。
$ git commit -m "move .gitignore outside also works."
[master 3488f2c] move .gitignore outside also works.
1 files changed, 0 insertions(+), 0 deletions(-)
rename src/.gitignore => .gitignore (100%)
忽略文件有错误,后果很严重
实际上面写的忽略文件不是非常好,为了忽略version.h,结果使用了通配符*.h会把源码目录下的有用的头文件也给忽略掉,导致应该添加到版本库的文件忘记添加。
在当前目录下创建一个新的头文件hello.h。
$ echo "/* test */" > hello.h
在工作区状态显示中看不到hello.h文件。
$ git status
# On branch master
nothing to commit (working directory clean)
只有使用了--ignored参数,才会在状态显示中看到被忽略的文件。
$ git status --ignored -s
!! hello
!! hello.h
!! main.o
!! version.h
要添加hello.h文件,使用git add -A和git add .都失效。无法用这两个命令将hello.h添加到暂存区中。
$ git add -A
$ git add .
$ git st -s
只有在添加操作的命令行中明确的写入文件名,并且提供-f参数才能真正添加。
$ git add -f hello.h
$ git commit -m "add hello.h"
[master 48456ab] add hello.h
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 src/hello.h
忽略只对未跟踪文件有效,对于已加入版本库的文件无效
文件hello.h添加到版本库后,就不再受到.gitignore设置的文件忽略影响了,对hello.h的修改都会立刻被跟踪到。这是因为Git的文件忽略只是对未入库的文件起作用。
$ echo "/* end */" >> hello.h
$ git status
# On branch master
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: hello.h
#
no changes added to commit (use "git add" and/or "git commit -a")
本地独享式忽略文件
文件.gitignore设置的文件忽略是共享式的。之所以称其为“共享式”,是因为.gitignore被添加到版本库后成为了版本库的一部分,当版本库共享给他人(克隆)或者把版本库推送(PUSH)到集中式的服务器(或他人的版本库),这个忽略文件就会出现在他人的工作区中,文件忽略在他人的工作区中同样生效。
与“共享式”忽略对应的是“独享式”忽略。独享式忽略就是不会因为版本库共享或者版本库之间的推送传递给他人的文件忽略。独享式忽略有两种方式:
一种是针对具体版本库的“独享式”忽略。即在版本库.git目录下的一个文件.git/info/exclude来设置文件忽略。
另外一种是全局的“独享式”忽略。即通过Git的配置变量core.excludesfile指定的一个忽略文件,其设置的忽略对所有文件均有效。
至于哪些情况需要通过向版本库中提交.gitignore文件设置共享式的文件忽略,哪些情况通过.git/info/exclude设置只对本地有效的独享式文件忽略,这取决于要设置的文件忽略是否具有普遍意义。如果文件忽略对于所有使用此版本库工作的人都有益,就通过在版本库相应的目录下创建一个.gitignore文件建立忽略,否则如果是需要忽略工作区中创建的一个试验目录或者试验性的文件,则使用本地忽略。
例如我的本地就设置着一个全局的独享的文件忽略列表(这个文件名可以随意设置):
$ git config --global core.excludesfile /home/jiangxin/_gitignore
$ git config core.excludesfile
/home/jiangxin/_gitignore
$ cat /home/jiangxin/_gitignore
*~ # vim 临时文件
*.pyc # python 的编译文件
.*.mmx # 不是正则表达式哦,因为 FreeMind-MMX 的辅助文件以点开头
Git忽略语法
Git的忽略文件的语法规则再多说几句。
忽略文件中的空行或者以井号(#)开始的行被忽略。
可以使用通配符,参见Linux手册:glob(7)。例如:星号(*)代表任意多字符,问号(?)代表一个字符,方括号([abc])代表可选字符范围等。
如果名称的最前面是一个路径分隔符(/),表明要忽略的文件在此目录下,而非子目录的文件。
如果名称的最后面是一个路径分隔符(/),表明要忽略的是整个目录,同名文件不忽略,否则同名的文件和目录都忽略。
通过在名称的最前面添加一个感叹号(!),代表不忽略。
下面的文件忽略示例,包含了上述要点:
# 这是注释行 —— 被忽略
*.a # 忽略所有以 .a 为扩展名的文件。
!lib.a # 但是 lib.a 文件或者目录不要忽略,即使前面设置了对 *.a 的忽略。
/TODO # 只忽略根目录下的 TODO 文件,子目录的 TODO 文件不忽略。
build/ # 忽略所有 build/ 目录下的文件。
doc/*.txt # 忽略文件如 doc/notes.txt,但是文件如 doc/server/arch.txt 不被忽略。
文件归档
如果使用压缩工具(tar、7zip、winzip、rar等)将工作区文件归档,一不小心会把版本库(.git目录)包含其中,甚至将工作区中的忽略文件、临时文件也包含其中。Git提供了一个归档命令:git archive,可以对任意提交对应的目录树建立归档。示例如下:
- 基于最新提交建立归档文件latest.zip。
$ git archive -o latest.zip HEAD
- 只将目录src和doc建立到归档partial.tar中。
$ git archive -o partial.tar HEAD src doc
- 基于里程碑v1.0建立归档,并且为归档中文件添加目录前缀1.0。
$ git archive --format=tar --prefix=1.0/ v1.0 | gzip > foo-1.0.tar.gz
在建立归档时,如果使用树对象ID进行归档,则使用当前时间作为归档中文件的修改时间,而如果使用提交ID或里程碑等,则使用提交建立的时间作为归档中文件的修改时间。
如果使用tar格式建立归档,并且使用提交ID或里程碑ID,还会把提交ID记录在归档文件的文件头中。记录在文件头中的提交ID可以通过git tar-commit-id命令获取。
如果希望在建立归档时忽略某些文件或目录,可以通过为相应文件或目录建立export-ignore属性加以实现。
Git-Git基本操作的更多相关文章
- Git/GitHub基本操作
GitGit是分布式版本控制工具,SVN是集中式版本控制,有单点故障的问题GitHub是Git的代码托管中心,类似的国内有码云,是远程维护库Git的优势大部分操作在本地完成,不需要联网完整性有保证尽可 ...
- Git GUI基本操作
一.Git GUI基本操作 1.版本库初始化 gitpractise文件夹就变成了Git可以管理的仓库,目录下多了一个.git文件夹,此目录是Git用于管理版本库的,不要擅自改动里面的文件,这样会破坏 ...
- 【转】Git GUI基本操作
一.Git GUI基本操作 1.版本库初始化 gitpractise文件夹就变成了Git可以管理的仓库,目录下多了一个.git文件夹,此目录是Git用于管理版本库的,不要擅自改动里面的文件,这样会破坏 ...
- Github学习之路-小试牛刀,练习Git 的基本操作
一.下子windows客户端. Git 客户端下载地址:http://msysgit.github.io/ 二.打开Git Bash 命令行操作界面. 安装完成后,在开始菜单里找到“Git”-> ...
- Git 版本管理基本操作
Git是一个版本管理操作的工具 非常N,可以很智能的分布式管理, 本网站学习笔记 来自于廖雪峰老师的内容借鉴 安装 yum -y install git 本地设置全局 告知是谁提交代码 信息 # gi ...
- git的基本操作---就看我这一篇就足够了!!!!!
git操作项目的大致步骤. git init //初始化一个本地仓库. git add . //添加文件 git commit -m '提交内容' //提交到本地仓库 git status //查看状 ...
- error setting certificate verify locations: CAfile: E:/git/Git/mingw64/ssl/certs/ca-bundle.crt
一.问题: 当git clone项目时报 error setting certificate verify locations: CAfile: E:/git/Git/mingw64/ssl/cert ...
- [git]git 分支
什么动作,关键看你想完成什么 1. 添加新的远程分支: git push origin current_local_branch:new_remote_branch 2. 删除远程分支(冒号前必须要有 ...
- [git] git 的基本认知
版本管理 ( Version Control ) 版本管理系统是一个记录文件变更的系统,让你在一段时间后可以恢复指定版本的文件.版本管理系统大致可分为三类:独立的本地版本管理系统.中心化版本管理系统. ...
- Git -> Can't start Git: git.exe
问题描述 导入别人的PyCharm项目后提示:Can't start Git:git.exe 解决办法 Git就是个类似插件,在Git的官网上注册个账号然后每次编译就会自动把程序上传到网上备份.可以方 ...
随机推荐
- Spring整合Struts2 注解版
1.jar包 <!--spring配置--> <dependency> <groupId>org.springframework</groupId> & ...
- 《C#高效编程》读书笔记09-避免在API中使用转换操作符
转换操作符为类之间引入了一种"可替换性"(substitutability)."可替换性"表示一个类的实例可以替换为另一个类的实例. public class ...
- 如何查看win10已激活密钥?查看win10已激活完整密钥的方法!
如何查看win10已激活密钥?查看win10已激活完整密钥的方法! HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/So ...
- innobackupex 全备、增备脚本
全备脚本:innobackupex --defaults-file=/etc/my.cnf --user root --password mypasswd /mydata/fullbak/ 增备脚本: ...
- BZOJ3932(主席树上二分+差分
按时间作为主席树的版本,每个版本的主席树都是一个权值线段树. 差分消去时间影响 对于当前时间版本的主席树查询前K大即可. 树上二分时结束后切记判定l==r的状态(易错 l==r叶子节点可能存在多个值( ...
- pip 安装出现异常
MacBookPro:~ mac$ pip install numpy Collecting numpy Downloading numpy-1.13.1-cp35-cp35m-macosx_10_6 ...
- Feign + Hystrix 服务熔断和服务降级
本机IP为 192.168.1.102 1. 新建 Maven 项目 feign 2. pom.xml <project xmlns="http://maven.apa ...
- VC-基础-WebBrowser控件中弹出新网页窗口
用webbrowser控件浏览网页时,常弹出新的网页窗口,若不做任何控制的话,会在默认浏览器(一般是IE)中打开,这样就在新的窗口打开了,原程序就很难控制了,且存在webbrowser控件和IE的se ...
- css属性选择器=,~=,^=,$=,*=,|=
http://www.w3school.com.cn/css/css_selector_attribute.asp =. property和value必须完全一致 : ~=.“约等于”?: ^=. 从 ...
- python linecache模块读取文件用法详解
linecache模块允许从任何文件里得到任何的行,并且使用缓存进行优化,常见的情况是从单个文件读取多行. linecache.getlines(filename) 从名为filename的文件中得到 ...