Node.js Git Server搭建及Git常用操作笔记
安装Git工具即可在本地进行Git仓库的管理,如果要实现远程仓库则需要搭建Git Server。通过Node.js搭建Git Server是比较方便的方式,如果通过Electron集成进行二次开发,可进一步实现类似Gitlab的扩展功能。
Node.js Git Server搭建
首先要安装Node.js,建议安装最新的发布版(长期维护版)。然后在PC上建一个目录作为Git Server的目录,这里将目录命名为git_server。
这里采用node-git-server模块来实现Git Server, 更多信息可以参阅官方介绍。
- 首先在git_server目录下,打开控制台,可以采用npm或cnpm镜像安装模块,如:
npm install node-git-server
或
npm install -g cnpm --registry=https://registry.npm.taobao.org
cnpm install node-git-server
- 进入git_server目录下的node_modules\_node-git-server@1.0.0-beta.30@node-git-server\example子目录,_node-git-server@1.0.0-beta.30这个名称随版本会变化,逮住node-git-server这个名称识别即可。
- 查阅index.js,这个文件是个范例,其内容如下。
// You Can Use The Commands Below To Generate A Self Signed Certificate For Use With This Tutorial
// These Commands Require That You have 'openssl' installed on your system
// openssl genrsa -out privatekey.pem 1024
// openssl req -new -key privatekey.pem -out certrequest.csr
// openssl x509 -req -in certrequest.csr -signkey privatekey.pem -out certificate.pem
let type = 'http';
process.argv.slice(2).forEach((arg) => {
switch (arg) {
case 'https':
case '--https':
type = 'https';
break;
}
});
const fs = require('fs');
const path = require('path');
const { Git : Server } = require("../");
const port = process.env.PORT || 7005;
const repos = new Server(path.normalize(path.resolve(__dirname, 'tmp')), {
autoCreate: true,
authenticate: ({ type, repo, user, headers }, next) => {
console.log(type, repo, headers); // eslint-disable-line
if (type == 'push') {
// Decide if this user is allowed to perform this action against this repo.
user((username, password) => {
if (username === '42' && password === '42') {
next();
} else {
next('wrong password');
}
});
} else {
// Check these credentials are correct for this user.
next();
}
},
});
repos.on('push', (push) => {
console.log(`push ${push.repo} / ${push.commit} ( ${push.branch} )`); // eslint-disable-line
repos.list((err, results) => {
push.log(' ');
push.log('Hey!');
push.log('Checkout these other repos:');
for (const repo of results) {
push.log(`- ${repo}`);
}
push.log(' ');
});
push.accept();
});
repos.on('fetch', (fetch) => {
console.log(`username ${fetch.username}`); // eslint-disable-line
console.log(`fetch ${fetch.repo}/${fetch.commit}`); // eslint-disable-line
fetch.accept();
});
repos.listen(
port,
{
type,
key: fs.readFileSync(path.resolve(__dirname, 'privatekey.pem')),
cert: fs.readFileSync(path.resolve(__dirname, 'certificate.pem')),
},
(error) => {
if(error) return console.error(`failed to start git-server because of error ${error}`); // eslint-disable-line
console.log(`node-git-server running at ${type}://localhost:${port}`); // eslint-disable-line
repos.list((err, result) => {
if (!result) {
console.log("No repositories available..."); // eslint-disable-line
} else {
console.log(result); // eslint-disable-line
}
});
}
);
-
修改仓库地址在如下代码进行,其中__dirname代表当前目录,可以用其它目录的绝对路径代替,__dirname后面一个参数是最后一级目录名,需要注意,设定后要确定这个目录存在或手动建立,否则后面运行会报错。
-
修改端口号通过如下的代码部分进行
-
如果要免访问账号密码使用,则要删除这段代码和一个逗号:
-
如果要有访问账号密码控制使用,则在如下位置进行用户名和密码设置,在有账号控制使用时,本地向Server做push的时候,会要求输入账号和密码:
如用户名为admin,密码为psw,则改为:
if (username === 'adm' && password === 'psw')
- 然后就可以在example目录,在控制台输入服务器启动指令:
node index
运行后会显示远程仓库的地址
下面的数组框里是当前服务器管理下的远程仓库名,初始时候是空数组。
从本地仓库向服务器第一次push就会在服务器的管理目录下建立起远程仓库。
这里push上去了两个git远程仓库,一个是demo.git, 一个是test.git。
Git常用操作
安装Git工具后,可以在需要进行Git管理的目录进行操作。
Windows操作系统用Git Bash操作,另外也可以用Git GUI的图形操作界面,通过Git Bash操作更能够理解Git运行原理。
Ubuntu等Linux系统则直接用控制台进行操作:
除了服务器侧代表的远程仓库,本地Git管理对应工作区,暂存区和本地仓库。另外Git管理又按照分支进行操作,每个分支对应自己的工作区,暂存区和本地仓库,一般本地仓库和远程仓库名相同。但在复杂操作下,版本间,分支间还可以“乱入”进行切换和合并。在最简单的情况下,一个分支的工作区文件,可以提交到暂存区,再由暂存区提交到本地版本仓库,再由本地版本仓库提交到服务器远程版本仓库,反向也可以从服务器远程拉回版本文件。
Git的常用操作介绍如下,以列表形式,便于查询:
I Want | Instruction | Descption |
---|---|---|
在当前目录建立git管理 | git init | 会在当前目录建立.git的管理目录,一般是隐藏目录 |
查询某条git指令的使用帮助如git log | git help log | 会弹出浏览器打开帮助网页 |
配置当前git操作者的姓名 | git config --global user.name “your name” | 去掉–global则只为当前目录的git管理设定 |
配置当前git操作者的邮箱 | git config --global user.email “xx@yy.com” | 去掉–global则只为当前目录的git管理设定 |
查询配置信息 | git config -l | |
提交工作区内容到暂存区 | git add filename 或 git add . | git add .是将当前目录下所有文件提交 |
提交暂存区内容到版本库 | git commit 或 git commit -m “comments” | 采用git commit会弹出VIM窗口,要求输入comments后保存退出 。VIM操作为:首先按i键进入插入模式;然后编辑文件;接着按esc键进入命令行模式;最后输入:wq即可保存文件并退出。 |
查看仓库状态 | git status | |
查看工作区和暂存区的区别 | git diff 或 git diff filename | git diff filename只查看单个文件的区别 ;如果暂存区没有提交,则会取对应的版本库内容代替进行比较 |
查看工作区和版本库的区别 | git diff head 或 git diff head filename | git diff head filename只查看单个文件的区别 |
查看暂存区和版本库的 | git diff --cached 或 git diff cached filename | git diff --cached filename只查看单个文件的区别 ;如果暂存区没有提交,则会取对应的版本库内容代替进行比较, 因此比较结果为无差异 |
查看提交历史 | git log 或 git log --pretty==oneline | –pretty==oneline表示在一行里显示信息。另外还有–decorate, --graph, --reverse, --author, --since, --before, --until, --after等后缀可用,可以查询使用帮助了解。git log只能查询当前版本及之前提交版本的信息。 |
查看包括之后提交的提交历史 | git reflog | 能查询当前版本及前后提交版本的信息。 |
查看指定文件的修改记录 | git blame filename | filename是文件名 |
当前版本回退到上一个版本 | git reset --hard HEAD^ | 版本库里包括当前版本至少要有两个版本提交历史 |
当前版本回退到上上一个版本 | git reset --hard HEAD^^ | 版本库里包括当前版本至少要有三个版本提交历史 |
当前版本回退到制定版本 | git reset --hard ‘commit _id’ | 通过git log可查询‘commit_id’ |
撤销工作区内容修改 | git checkout – . 或 git checkout – filename 或 git restore – . 或 git restore filename | git checkout – filename和git restore filename对单个文件操作。git restore在较新的版本上支持。撤销修改操作,如果暂存区有内容,参考暂存区内容进行。如果暂存区没有内容,则参考版本库的当前版本进行 |
撤回暂存区的提交文件 | git reset HEAD . 或 git reset HEAD filename | git reset HEAD filename只撤回单个文件。此操作只清除暂存区文件,不对工作区文件产生影响 |
删除当前版本库中的文件 | git rm filename | 只能删除本地版本库的文件,不能删除远程版本库的文件,可以push一个去除文件的版本到远程版本库代替 |
查看分支信息 | git branch 或 git branch -v 或git branch -a 或 git branch -av | -v表示查看详细信息,-a表示也查看远程分支信息 |
创建本地分支 | git branch branchname | branchname是分支名 |
切换本地分支 | git checkout branchname 或 git switch branchname | 切换分支时,本地工作文件会被切换到的分支的版本库文件替换,暂存区为空。如果切换前,当前分支工作区文件,暂存区文件和版本库文件不一致,则切换分支时会告警,要求使用commit产生一致(三区一致,或者暂存区为空的两区一致),或者用”git stash”保存当前数据(以便以后切换回来后进行数据恢复),这是为了切换分支之后,再切换回来原分支时不丢失原分支的数据 |
创建并切换本地分支 | git checkout -b branchname 或 git switch -c branchname | |
合并分支 | git merge branchname | 在当前分支下合并branchname的分支。当从master分支合并一个分支如dev分支时,dev分支的版本库提交时间应该晚于master分支版本库的提交时间,合并才能进行,也就是被合并进来的应该是“更新”的修改数据的概念。在master分支合并入dev分支时,合并内容呈现在master分支,dev分支原有的内容不变。反之,在dev分支合并入master分支时,合并内容呈现在dev分支,master分支原有的内容不变。 一些情况下会产生冲突,则在工作区对文件进行确认校正后再重新提交到本地版本库即可 |
删除本地仓库分支 | git branch -d branchname | |
删除远程仓库分支 | git push origin --delete branchname 或者 git push origin :branchname | origin是远程仓库别名,通过git remote add指令预设 |
本地没有版本,从远程仓库拉一个版本 | git clone remote_repo_addr | remote_repo_addr是远程仓库地址,如http://aaa.bbb.ccc/repo,git或aaa@bbb.ccc/git/repo.git等形式,也可以用https协议 |
添加远程仓库别名 | git remote add origin remote_repo_addr | 给远程仓库地址设置一个简短的别名,这里origin可以任意设置,只要随后对应使用即可。并可以给不同的远程仓库地址添加不同的别名, 如 git remote add origin http://localhost:7005/test.git 。 |
推送本地仓库的版本到远程仓库 | git push -u origin master 或 git push origin master | -u参数为从本地仓库当前分支第一次向远程仓库推送时起到关联作用。origin是远程仓库别名,master是推送的分支,一般情况下,本地仓库和远程仓库关联的分支同名。进行分支推送时,可以在master分支推送dev分支到远程仓库,而不必一定要在dev分支做dev分支的远程仓库推送。 |
从远程仓库拉版本更新下来 | git fetch origin master | 将远程仓库origin/master的分支当前版本拉下来后,是存放在了FETCH_HEAD的临时分支,可以后续操作在master分支进行FETCH_HEAD分支的merge ,即git merge FETCH_HEAD |
从远程仓库拉版本更新下来并和当前分支自动合并 | git pull origin master | 相当于git fetch指令和git merge指令的合用, FETCH_HEAD临时分支不能通过”git branch”指令查询到,预计在被merge后会被自动删除。 |
修改远程仓库别名对应地址 | git remote set-url origin url | 修改origin指向的地址,相当于git remote remove origin和git remote add origin url的合用 |
删除远程仓库别名 | git remote remove origin | |
给当前版本添加标签 | git tag -a ‘tagname’ -m ‘comments’ | |
给某个版本添加标签 | git tag -a ‘tagname’ -m ‘comments’ ‘commit_id’ | 其中,tagname和comment自行定义,而commit_id通过”git log”查询得到 |
查询本地仓库的标签 | git tag | |
查看本地仓库某个标签信息 | git tag ‘tagname’ | |
推送某个标签到远程仓库 | git push origin ‘tagname’ | |
推送所有标签到远程仓库 | git push origin --tags | |
删除某个本地标签 | git tag -d ‘tagname’ | |
删除远程标签 | git push origin --delete ‘tagname’ 或 git push origin :‘tagname’ | |
临时保存当前分支数据 | git stash | 对于本地仓库的当前版本,在做merge后或从远程仓库pull后会得到更新,如果要在更新前临时保存当前版本,以便必要时去掉更新恢复原来版本,就要用到”git stash”功能。有提交到暂存区及版本库,此时执行切换分支操作,则会反馈告警,此时也需要通过git stash进行临时保存,或者完成提交到版本库,然后再进行分支切换,由此可见,git stash保存的是当前分支的工作文件,暂存区和版本库整体 |
查看临时保存的分支数据 | git stash list | |
恢复最近一次临时保存的分支数据 | git stash pop | |
恢复全部临时保存的分支数据 | git stash apply | |
丢弃临时保存的分支数据 | git stash clear | |
想回滚已提交到暂存区的内容到工作区,但提交后的工作区内容修改不想被覆盖 | git reset --soft | |
想回滚已提交到版本区的内容到暂存区,但提交后的又修改的暂存区内容不想被覆盖 | git reset --mixed | |
想回滚已提交到版本区的内容到暂存区和工作区,但提交后的工作区内容和又修改的暂存区内容不想被覆盖 | git reset --hard | |
改变当前分支的版本对应到另一个分支上,如从dev分支变基到master分支 | git rebase master | 在dev分支执行变基到master分支,两个分支公共版本节点之后的dev版本节点,会被顺序添加到master分支最后一个版本节点后,且忽略与master节点最后一个版本节点的时间关系 |
只想把分支A的一个版本和之前一个版本之间的修改合并到B分支的当前版本 | git cherry-pick ‘commit_id’ | commit_id属于分支A,通过git log查询 |
–End–