从一个git仓库拷贝到另一个git仓库

利用git从一个仓库拷贝一个项目到另一个仓库,并且log也能够一起过去。

1、从原地址克隆一份裸版本库,比如原本托管于 GitHub。
git clone –bare http://github….(原始仓库地址)

2、进入克隆下来的目录
cd project.git(project即为你的项目名称)

3、以镜像推送的方式上传代码到新的仓库地址。
git push –mirror http://…(目标仓库地址)

Git切换到指定的提交(commit)

方法一,新分支
1.1Git查找commitId

$git log
commit cbcf45ec166eee4ca0ade2dc78f1445f7d39f0ab

1.2 检出提交

git checkout cbcf45ec166e
检查提交到新的分支
git checkout -b old-state cbcf45ec166e
-b参数会为提交新建一个分支。

方法二,回滚
git reset –hard 046bd7b5c1d134b8123f59ea71b19875a6a2fc3e

git切换到某个tag

git clone 整个仓库后使用,以下命令就可以取得该 tag 对应的代码了。

git checkout tag_name
但是,这时候 git 可能会提示你当前处于一个“detached HEAD” 状态。

因为 tag 相当于是一个快照,是不能更改它的代码的。

如果要在 tag 代码的基础上做修改,你需要一个分支:

git checkout -b branch_name tag_name
这样会从 tag 创建一个分支,然后就和普通的 git 操作一样了。

如果项目上有一个后来新建的分支test,并且使用

git branch -a
看不到该远程分支:

* develop
remotes/composer/develop
remotes/composer/feature/194
remotes/composer/feature/198
remotes/composer/feature/199
remotes/composer/feature/200
remotes/composer/master
remotes/origin/HEAD -> origin/develop
remotes/origin/develop
remotes/origin/feature/194
remotes/origin/feature/198
remotes/origin/feature/199
remotes/origin/feature/200
remotes/origin/master
直接使用命令git checkout test,出现以下错误

error: pathspec ‘origin/XXX’ did not match any file(s) known to git.
项目上有一个分支test,使用git branch -a看不到该远程分支,直接使用命令git checkout test报错如下:
解决方法是:

1、执行命令git fetch取回所有分支的更新

2、执行git branch -a可以看到test分支(已经更新分支信息)

3、切换分支git checkout test

git结合TortoiseGit使用sshkey,无需输入账号和密码

1 找到TortoiseGit自带的Puttygen工具
2 打开之后,选择Generate(生成的过程中记得移动鼠标)
putty key generator
3生成完毕之后,将上面的公钥设置到github上面
github的设置界面,有sshkeys,添加进去就可以了
4 保存一下私钥到本地
保存之前,先设置一个私钥的密码【上面的passphrase】
5将私钥加到远端设置中
remote:名字
URL:git@172.16.20.27:/git/data/sample.git
putty key 上述生成的Key

Git 分支管理

几乎每一种版本控制系统都以某种形式支持分支。使用分支意味着你可以从开发主线上分离开来,然后在不影响主线的同时继续工作。

有人把 Git 的分支模型称为必杀技特性,而正是因为它,将 Git 从版本控制系统家族里区分出来。

创建分支命令
git branch (branchname)

切换分支命令:
git checkout (branchname)
当你切换分支的时候,Git 会用该分支的最后提交的快照替换你的工作目录的内容, 所以多个分支不需要多个目录。

合并分支命令:
git merge (branchname)
你可以多次合并到统一分支, 也可以选择在合并之后直接删除被并入的分支。

开始前我们先创建一个测试目录:

$ mkdir gitdemo
$ cd gitdemo/
$ git init
Initialized empty Git repository…
$ touch README
$ git add README
$ git commit -m ‘第一次版本提交’
[master (root-commit) 3b58100] 第一次版本提交
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 README
Git 分支管理
列出分支
列出分支基本命令:

git branch
没有参数时,git branch 会列出你在本地的分支。

$ git branch
* master
此例的意思就是,我们有一个叫做 master 的分支,并且该分支是当前分支。

当你执行 git init 的时候,默认情况下 Git 就会为你创建 master 分支。

如果我们要手动创建一个分支。执行 git branch (branchname) 即可。

$ git branch testing
$ git branch
* master
testing
现在我们可以看到,有了一个新分支 testing。

当你以此方式在上次提交更新之后创建了新分支,如果后来又有更新提交, 然后又切换到了 testing 分支,Git 将还原你的工作目录到你创建分支时候的样子。

接下来我们将演示如何切换分支,我们用 git checkout (branch) 切换到我们要修改的分支。

$ ls
README
$ echo ‘runoob.com’ > test.txt
$ git add .
$ git commit -m ‘add test.txt’
[master 3e92c19] add test.txt
1 file changed, 1 insertion(+)
create mode 100644 test.txt
$ ls
README test.txt
$ git checkout testing
Switched to branch ‘testing’
$ ls
README
当我们切换到 testing 分支的时候,我们添加的新文件 test.txt 被移除了。切换回 master 分支的时候,它们有重新出现了。

$ git checkout master
Switched to branch ‘master’
$ ls
README test.txt
我们也可以使用 git checkout -b (branchname) 命令来创建新分支并立即切换到该分支下,从而在该分支中操作。

$ git checkout -b newtest
Switched to a new branch ‘newtest’
$ git rm test.txt
rm ‘test.txt’
$ ls
README
$ touch runoob.php
$ git add .
$ git commit -am ‘removed test.txt、add runoob.php’
[newtest c1501a2] removed test.txt、add runoob.php
2 files changed, 1 deletion(-)
create mode 100644 runoob.php
delete mode 100644 test.txt
$ ls
README runoob.php
$ git checkout master
Switched to branch ‘master’
$ ls
README test.txt
如你所见,我们创建了一个分支,在该分支的上移除了一些文件 test.txt,并添加了 runoob.php 文件,然后切换回我们的主分支,删除的 test.txt 文件又回来了,且新增加的 runoob.php 不存在主分支中。

使用分支将工作切分开来,从而让我们能够在不同开发环境中做事,并来回切换。

删除分支
删除分支命令:

git branch -d (branchname)
例如我们要删除 testing 分支:

$ git branch
* master
testing
$ git branch -d testing
Deleted branch testing (was 85fc7e7).
$ git branch
* master
分支合并
一旦某分支有了独立内容,你终究会希望将它合并回到你的主分支。 你可以使用以下命令将任何分支合并到当前分支中去:

git merge
$ git branch
* master
newtest
$ ls
README test.txt
$ git merge newtest
Updating 3e92c19..c1501a2
Fast-forward
runoob.php | 0
test.txt | 1 –
2 files changed, 1 deletion(-)
create mode 100644 runoob.php
delete mode 100644 test.txt
$ ls
README runoob.php
以上实例中我们将 newtest 分支合并到主分支去,test.txt 文件被删除。

合并完后就可以删除分支:

$ git branch -d newtest
Deleted branch newtest (was c1501a2).
删除后, 就只剩下 master 分支了:

$ git branch
* master
合并冲突
合并并不仅仅是简单的文件添加、移除的操作,Git 也会合并修改。

$ git branch
* master
$ cat runoob.php
首先,我们创建一个叫做 change_site 的分支,切换过去,我们将 runoob.php 内容改为:


创建 change_site 分支:

$ git checkout -b change_site
Switched to a new branch ‘change_site’
$ vim runoob.php
$ head -3 runoob.php

$ git commit -am ‘changed the runoob.php’
[change_site 7774248] changed the runoob.php
1 file changed, 3 insertions(+)

将修改的内容提交到 change_site 分支中。 现在,假如切换回 master 分支我们可以看内容恢复到我们修改前的(空文件,没有代码),我们再次修改 runoob.php 文件。

$ git checkout master
Switched to branch ‘master’
$ cat runoob.php
$ vim runoob.php # 修改内容如下
$ cat runoob.php

$ git diff
diff –git a/runoob.php b/runoob.php
index e69de29..ac60739 100644
— a/runoob.php
+++ b/runoob.php
@@ -0,0 +1,3 @@
+
$ git commit -am ‘修改代码’
[master c68142b] 修改代码
1 file changed, 3 insertions(+)
现在这些改变已经记录到我的 “master” 分支了。接下来我们将 “change_site” 分支合并过来。

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

$ cat runoob.php # 代开文件,看到冲突内容
<<<<<<< HEAD echo 1; ======= echo ‘runoob’; >>>>>>> change_site
?>
我们将前一个分支合并到 master 分支,一个合并冲突就出现了,接下来我们需要手动去修改它。

$ vim runoob.php
$ cat runoob.php

$ git diff
diff –cc runoob.php
index ac60739,b63d7d7..0000000
— a/runoob.php
+++ b/runoob.php
@@@ -1,3 -1,3 +1,4 @@@

在 Git 中,我们可以用 git add 要告诉 Git 文件冲突已经解决

$ git status -s
UU runoob.php
$ git add runoob.php
$ git status -s
M runoob.php
$ git commit
[master 88afe0e] Merge branch ‘change_site’
现在我们成功解决了合并中的冲突,并提交了结果。

Git 工作区、暂存区和版本库

基本概念
我们先来理解下Git 工作区、暂存区和版本库概念

工作区:就是你在电脑里能看到的目录。
暂存区:英文叫stage, 或index。一般存放在 “.git目录下” 下的index文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
版本库:工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
下面这个图展示了工作区、版本库中的暂存区和版本库之间的关系:

图中左侧为工作区,右侧为版本库。在版本库中标记为 “index” 的区域是暂存区(stage, index),标记为 “master” 的是 master 分支所代表的目录树。

图中我们可以看出此时 “HEAD” 实际是指向 master 分支的一个”游标”。所以图示的命令中出现 HEAD 的地方可以用 master 来替换。

图中的 objects 标识的区域为 Git 的对象库,实际位于 “.git/objects” 目录下,里面包含了创建的各种对象及内容。

当对工作区修改(或新增)的文件执行 “git add” 命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中。

当执行提交操作(git commit)时,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。

当执行 “git reset HEAD” 命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。

当执行 “git rm –cached ” 命令时,会直接从暂存区删除文件,工作区则不做出改变。

当执行 “git checkout .” 或者 “git checkout — ” 命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区的改动。

当执行 “git checkout HEAD .” 或者 “git checkout HEAD ” 命令时,会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。

Git-Gui的中文乱码解决方法

在Windows下使用Git-Gui时,可能会出现代码中的中文乱码的情况。
解决方法:
在软件的安装目录下,在Git\mingw64\etc\gitconfig文件末尾添加:

[gui]
encoding=utf-8

这样代码中的中文就能够正常显示了。

另外 关于软件的其他部分的软件相关中文乱码,解决方法如下:
打开软件,在Edit -> Preferences -> fonts 中修改相应的配置即可。

最简git服务器搭建和测试

git是一个开源的版本管理软件,通过git可以方便地进行软件的协同开发、历史回溯等,下面是一个最简单的git服务器搭建和测试步骤,为了方便,后面还有一个一键自动化搭建的脚本。前提是对git有一定了解,并且已经安装好git。
1.sudo apt-get install git openssh-server openssh-client
2.useradd -r -s /sbin/nologin git
3.ssh-keygen -C “12345@qq.com”
4.touch /home/git/.ssh/authorized_keys
5.mkdir -p /data/git && cd /data/git
git init –bare sample.git && chown -R git.git /data/git
6.git clone ssh://git@192.168.20.27:5270/home/git/code/sample.git

一、最简git服务器搭建和测试

服务端搭建:

说明:搭建一个空的hello.git的远程仓库(ip:192.168.1.155)

1.添加git用户

sudo useradd -m git

sudo passwdgit

su git

2.进入/home/git并初始化空的仓库,结果如图1所示,创建了一个名为hello.git的代码仓库

cd /home/git

git init –bare hello.git

图1 hello.git代码仓库

客户端测试:

说明:初始化一个本地仓库,然后推送到服务端

1.新建一个hello的目录,并写一段helloworld的代码

2.在hello目录下创建一个git仓库,并提交一次

git init

git add –all

git commit

3.添加远程代码仓库

git remote add origingit@192.168.1.155:/home/git/hello.git

4.推送master分支到远程,执行结果如图2所示,服务端多了一个master分支

git push origin master

图2 客户端测试流程

5.到另外一个目录下克隆远程仓库

git clonegit@192.168.1.155:/home/git/hello.git

二、最简git服务器自动化搭建脚本

说明:创建git仓库并搭建一个空的hello.git的远程仓库(ip:192.168.1.155)

脚本源码:

gitnew.sh:

#!/bin/sh

parmNum=$#

if [ $parmNum -eq 0 ];then

echo “Run as:”

echo “1.Create git account and repertory: ./gitnew.sh repertory”

echo “2.Create git account only: ./gitnew.sh null”

exit

fi

repertory=$1

echo “[$0]:Add git account:”

sudo useradd -m git

echo “[$0]:Passwd git account:”

sudo passwd git

if [ $repertory != “null” ];then

cd /home/git

repertory_git=”$repertory.git”

echo “[$0]:Create $repertory_git”

sudo git init –bare $repertory_git

sudo chown -R git:git $repertory_git

cd –

fi

echo “[$0]:Enjoy”

运行结果:

脚本运行完成之后,如图3所示,创建好了一个hello.git的远程仓库,跟上面的一模一样。

图3 自动化脚本创建代码仓库

三、解决客户端推送和克隆要输入服务端git登录密码的问题

1.在服务端/home/git目录下新建一个.ssh目录

mkdir .ssh

2.在.ssh目录下新建一个authorized_keys文件

touch authorized_keys

3.把客户端的ssh公钥写到authorized_keys文件中,一行一个

echo **** >>authorized_keys

Gitweb最简安装

1.安装gitweb程序
sudo apt-get install gitweb apache2
安装完成后,会自动生成/etc/gitweb.conf和/etc/apache2/conf-available/gitweb.conf两个文件。

2.配置git服务端
根目录修改/etc/gitweb.conf 中的$projectroot 为:
$projectroot = “/home/git” ;

3.启动gitweb服务
重启Apache服务器:
sudo service apache2 restart

4.测试
在客户端输入:http://192.168.1.155/gitweb/ 即可看到新建的项目。

5.安装CGI.pm
linux下perl及cgi.pm的安装(perl-5.22.1)
1.下载并解压perl-5.22.1(或者其他什么版本)
2.执行./Configure -des -Dprefix=/usr/local/perl
3.make ; make install;
4.建立软链接到/usr/bin
ln -s /usr/local/perl/bin/perl /usr/bin/perl
这里注意一下,若是之前安装过perl的话,需要先把/usr/local/下的perl改名或者删除什么的
5.如果没有意外,这就安装成功了.可以使用 perl -v查看版本信息什么的

安装CGI.pm的步骤
1.执行 perl -MCPAN -e shell
2.执行 install CGI.pm
3.没有以外的话这个模块也就安装成功了
可以在终端里执行 perl -MCGI -e ‘print “CGI.pm version $CGI::VERSION\n”;’ 这条命令来验证是否安装成功
如果出现 CGI.pm version 4.26 这种显示CGI版本的文本,恭喜你.