Linux用户和用户组管理

Linux用户和用户组管理

与用户和用户组相关的信息都存放在一些系统文件中,这些文件包括/etc/passwd, /etc/shadow, /etc/group等。完成用户管理的工作有许多种方法,但是每一种方法实际上都是对有关的系统文件进行修改。

用户管理

每个用户账号都拥有一个惟一的用户名和各自的口令。

用户在登录时键入正确的用户名和口令后,就能够进入系统和自己的主目录。

实现用户账号的管理,要完成的工作主要有如下几个方面:

  • 用户账号的添加、删除与修改。
  • 用户口令的管理。
  • 用户组的管理。

用户账号的管理

添加账号: useradd

1
useradd 选项 用户名

参数说明:

选项:

  • -c comment 指定一段注释性描述。
  • -d 目录 指定用户主目录,如果此目录不存在,则同时使用-m选项,可以创建主目录。
  • -g 用户组 指定用户所属的用户组。
  • -G 用户组,用户组 指定用户所属的附加组。
  • -s Shell文件 指定用户的登录Shell。
  • -u 用户号 指定用户的用户号,如果同时有-o选项,则可以重复使用其他用户的标识号。

用户名:
指定新账号的登录名。

1
# useradd –d /usr/sam -m sam

此命令创建了一个用户sam,其中-d和-m选项用来为登录名sam产生一个主目录/usr/sam(/usr为默认的用户主目录所在的父目录)。

1
# useradd -s /bin/sh -g group –G adm,root gem

此命令新建了一个用户gem,该用户的登录Shell是 /bin/sh,它属于group用户组,同时又属于adm和root用户组,其中group用户组是其主组。

这里可能新建组:#groupadd group及groupadd adm

增加用户账号就是在/etc/passwd文件中为新用户增加一条记录,同时更新其他系统文件如/etc/shadow, /etc/group等。

删除账号 userdel

如果一个用户的账号不再使用,可以从系统中删除。删除用户账号就是要将/etc/passwd等系统文件中的该用户记录删除,必要时还删除用户的主目录。
删除一个已有的用户账号使用userdel命令,其格式如下:

1
userdel 选项 用户名

常用的选项是 -r,它的作用是把用户的主目录一起删除。

1
# userdel -r sam

修改账号 usermod

修改用户账号就是根据实际情况更改用户的有关属性,如用户号、主目录、用户组、登录Shell等。

修改已有用户的信息使用usermod命令,其格式如下:

1
usermod 选项 用户名

常用的选项包括-c, -d, -m, -g, -G, -s, -u以及-o等,这些选项的意义与useradd命令中的选项一样,可以为用户指定新的资源值。

1
# usermod -s /bin/ksh -d /home/z –g developer sam

此命令将用户sam的登录Shell修改为ksh,主目录改为/home/z,用户组改为developer。

密码管理(口令)

用户管理的一项重要内容是用户口令的管理。用户账号刚创建时没有口令,但是被系统锁定,无法使用,必须为其指定口令后才可以使用,即使是指定空口令。

指定和修改用户口令的Shell命令是passwd。超级用户可以为自己和其他用户指定口令,普通用户只能用它修改自己的口令。命令的格式为:

1
passwd 选项 用户名

可使用的选项:

  • -l 锁定口令,即禁用账号。
  • -u 口令解锁。
  • -d 使账号无口令。
  • -f 强迫用户下次登录时修改口令。
    如果默认用户名,则修改当前用户的口令。

例如,假设当前用户是sam,则下面的命令修改该用户自己的口令:

1
2
3
4
$ passwd 
Old password:******
New password:*******
Re-enter new password:*******

如果是超级用户,可以用下列形式指定任何用户的口令:

1
2
3
# passwd sam 
New password:*******
Re-enter new password:*******

用户组管理

添加组 groupadd

1
groupadd 选项 用户组

可以使用的选项有:(选项不常用)

-g GID 指定新用户组的组标识号(GID)。
-o 一般与-g选项同时使用,表示新用户组的GID可以与系统已有用户组的GID相同。

1
# groupadd group1

此命令向系统中增加了一个新组group1,新组的组标识号是在当前已有的最大组标识号的基础上加1。

1
# groupadd -g 101 group2

此命令向系统中增加了一个新组group2,同时指定新组的组标识号是101。

删除组 groupdel

1
2
3
groupdel 用户组

# groupdel group1

修改组 groupmod

1
groupmod 选项 用户组

常用的选项有:

  • -g GID 为用户组指定新的组标识号。
  • -o 与-g选项同时使用,用户组的新GID可以与系统已有用户组的GID相同。
  • -n 新用户组 将用户组的名字改为新名字

切换

如果一个用户同时属于多个用户组,那么用户可以在用户组之间切换,以便具有其他用户组的权限

1
$ newgrp root

这条命令将当前用户切换到root用户组,前提条件是root用户组确实是该用户的主组或附加组。

Linux 文件属性

Linux 文件属性

在Linux中我们可以使用命令来显示一个文件的属性以及文件所属的用户和组,如:

1
2
3
4
5
[root@www /]# ls -l
total 64
dr-xr-xr-x 2 root root 4096 Dec 14 2012 bin
dr-xr-xr-x 4 root root 4096 Apr 19 2012 boot
……

note: “ll” 也可以。

在Linux中第一个字符代表这个文件是目录、文件或链接文件等等。”d”在Linux中代表该文件是一个目录文件。

  • 当为[ d ]则是目录
  • 当为[ - ]则是文件;
  • 若是[ l ]则表示为链接文档(link file);
  • 若是[ b ]则表示为装置文件里面的可供储存的接口设备(可随机存取装置);
  • 若是[ c ]则表示为装置文件里面的串行端口设备,例如键盘、鼠标(一次性读取装置)。

接下来的字符中,以三个为一组,且均为『rwx』 的三个参数的组合。

  • [ r ]代表可读(read)
  • [ w ]代表可写(write)
  • [ x ]代表可执行(execute)

要注意的是,这三个权限的位置不会改变,如果没有权限,就会出现减号[ - ]而已。

对于文件来说,它都有一个特定的所有者,也就是对该文件具有所有权的用户。同时,在Linux系统中,用户是按组分类的,一个用户属于一个或多个组。文件所有者以外的用户又可以分为文件所有者的同组用户和其他用户。因此,Linux系统按文件所有者、文件所有者同组用户和其他用户来规定了不同的文件访问权限。

对于 root 用户来说,一般情况下,文件的权限对其不起作用。

Linux文件内容查看

Linux文件内容查看

Linux文件内容查看

Linux 文件内容查看
Linux系统中使用以下命令来查看文件的内容:

  • cat 由第一行开始显示文件内容
  • tac 从最后一行开始显示,可以看出 tac 是 cat 的倒著写!
  • nl 显示的时候,顺道输出行号!
  • more 一页一页的显示文件内容
  • less 与 more 类似,但是比 more 更好的是,他可以往前翻页!
  • head 只看头几行
  • tail 只看尾巴几行

cat (由第一行开始显示文件内容)

语法:

1
cat [-AbEnTv]

参数:

  • -A :相当於 -vET 的整合选项,可列出一些特殊字符而不是空白而已;
  • -b :列出行号,仅针对非空白行做行号显示,空白行不标行号
  • -E :将结尾的断行字节 $ 显示出来;
  • -n :列印出行号,连同空白行也会有行号,与 -b 的选项不同;
  • -T :将 [tab] 按键以 ^I 显示出来;
  • -v :列出一些看不出来的特殊字符
    检看 /etc/issue 这个文件的内容:
    1
    2
    3
    [root@www ~]# cat /etc/issue
    CentOS release 6.4 (Final)
    Kernel \r on an \m

Maven 添加阿里云镜像

Maven 添加阿里云镜像

setting.xml

1
2
3
4
5
6
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>*</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>

log4j

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
### 设置###
log4j.rootLogger = debug,stdout,D,E

### 输出信息到控制台 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

### 输出DEBUG 级别以上的日志文件设置 ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = logs/debug.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n

### 输出ERROR 级别以上的日志文件设置 ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File = logs/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n

测试 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.test.util;

import org.apache.log4j.*;

public class LogUtil {
private static Logger logger = Logger.getLogger(LogUtil.class);

public static void main(String[] args) throws Exception {
// 记录debug级别的信息
logger.debug("This is debug message.");
// 记录info级别的信息
logger.info("This is info message.");
// 记录error级别的信息
logger.error("This is error message.");
}
}

Linux Java 安装环境变量

Linux Java 安装环境变量

如下安装目录为 /usr/java

1
2
3
4
5
tar -zxf jdk-8u211-linux-x64.tag.gz
vim etc/profile
export JAVA_HOME=/usr/java/jdk-8u221
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

修改.bash_profile文件

这种方法更为安全,它可以把使用这些环境变量的权限控制到用户级别,如果你需要给某个用户权限使用这些环境变量,你只需要修改其个人用户主目录下的.bash_profile文件就可以了。
·用文本编辑器打开用户目录下的.bash_profile文件
·在.bash_profile文件末尾加入:

1
2
3
export JAVA_HOME=/usr/java/jdk-8u221
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

String StringBuffer 和 StringBuilder

String、StringBuffer 和 StringBuilder

可变性

String:

简单的来说:String 类中使用 final 关键字修饰字符数组来保存字符串,private final char value[],所以 String 对象是不可变的。

StringBuilder 与 StringBuffer:

而StringBuilder 与 StringBuffer 都继承自 AbstractStringBuilder 类,
在 AbstractStringBuilder 中也是使用字符数组保存字符串char[]value 但是没有用 final 关键字修饰,所以这两种对象都是可变的。

线程安全性

String 中的对象是不可变的,也就可以理解为常量,线程安全。

AbstractStringBuilder 是 StringBuilder 与 StringBuffer 的公共父类,定义了一些字符串的基本操作,
如 expandCapacity、append、insert、indexOf 等公共方法。

StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。

StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的。 

对于三者使用的总结:

操作少量的数据: 适用String

单线程操作字符串缓冲区下操作大量数据: 适用StringBuilder

多线程操作字符串缓冲区下操作大量数据: 适用StringBuffer

装箱与拆箱

  • 装箱:将基本类型用它们对应的引用类型包装起来;
  • 拆箱:将包装类型转换为基本数据类型;

JVM 4.0

Class文件

Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在Class文件中,
中间没有添加任何分隔符号。Class文件采用一种类似于C语言结构体的伪结构来存储数据,这种伪结构中只包含两种数据类型,
无符号数和表。无符号数属于基本的数据类型,以u1,u2,u4,u8分别代表1个字节,2个字节,4个字节和8个字节的无符号数,
可以用来描述数字、索引引用、数量值或者按照utf-8编码构成字符串值。表是由多个无符号数或者其他表作为数据项构成的
复合数据类型,所有表都习惯性地以“_info”结尾,用来描述有层次关系的复合结构数据。

Class文件的内容包括:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
ClassFile {

u4 magic; //魔数:0xCAFEBABE,用来判断是否是Java class文件
u2 minor_version; //次版本号
u2 major_version; //主版本号
u2 constant_pool_count; //常量池大小
cp_info constant_pool[constant_pool_count-1]; //常量池
u2 access_flags; //类和接口层次的访问标志(通过|运算得到)
u2 this_class; //类索引(指向常量池中的类常量)
u2 super_class; //父类索引(指向常量池中的类常量)
u2 interfaces_count; //接口索引计数器
u2 interfaces[interfaces_count]; //接口索引集合
u2 fields_count; //字段数量计数器
field_info fields[fields_count]; //字段表集合
u2 methods_count; //方法数量计数器
method_info methods[methods_count]; //方法表集合
u2 attributes_count; //属性个数
attribute_info attributes[attributes_count]; //属性表

}
  • 访问标志:类还是接口;是否定义为public类型,abstract类型;若为类,是否声明为final。
  • 字段:用来描述接口或类中的变量,但不包括在方法内部的变量。
  • 字面量:文本字符串,声明为final的常量值等。
  • 符号引用:类和接口的全限定名;字段的名称和描述符;方法的名称和描述符。
  • 类索引,父类索引,接口索引:用来确定类的继承关系。

JVM 3.0

Java虚拟机的内部体系结构

在 Java虚拟机规范中,一个虚拟机实例的行为是分别按照子系统、内存区、数据类型和指令来描述的,
这些组成部分一起展示了抽象的虚拟机内部体系结构。

image

运行时数据区

Java虚拟机在执行Java程序的时候会把它管理的内存划分为若干个不同的数据区域,这些区域有各自的用途以及创建
和销毁的时机,有的区域随着虚拟机进程的启动而存在(线程共享),有的区域则随着用户线程的启动和结束而建立
和销毁(线程私有)。Java虚拟机所管理的内存包括以下几个运行时数据区域:

程序计数器

对于一个运行中的Java程序而言,每一个线程都有它的程序计数器,也叫PC寄存器,可以看做当前线程所执行的字节
码的行号指示器。在虚拟机的概念模型里,字节码解释器就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,
分支,循环,跳转,异常处理,线程恢复等都需要依赖这个计数器。

程序计数器既能持有一个本地指针,也能持有一个returnAddress。当线程执行某个Java方法时,程序计数器的值总是
下一条被执行指令的地址。这里的地址可以是一个本地指针,也可以是方法字节码中相对该方法起始指令的偏移量。
如果该线程正在执行一个本地方法,那么此时程序计数器的值是“undefined”。
程序计数器属于线程私有的内存,也就是说,每当创建一个线程,都将得到该线程自己的一个程序计数器。
Java虚拟机的多线程是通过线程的轮换并且分配处理器的执行时间来实现的,在一个确定的时刻,一个处理器都只会执行一条
线程中的指令。

为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器。

Java虚拟机栈(Java栈)

Java虚拟机栈也是线程私有的,它的生命周期和线程相同。Java虚拟机栈描述的是Java方法执行的内存模型,每个方法在执行时会创建一个栈帧,用于存放局部变量表,操作数栈,动态链接,方法出口等信息。一个Java方法从调用到执行结束的过程,相当于一个栈帧在Java虚拟机栈中从入栈到出栈的过程。

局部变量表

局部变量表用于存放编译时期可知的各种基本数据类型,对象的引用(不等同于对象,可能是指向对象的起始地址的指针,也可
能是指向一个代表对象的句柄)以及returnAddress类型(指向了一条字节码地址)。局部变量在方法执行时被创建,
在方法执行结束时销毁。字节码指令通过从0开始的索引使用其中的数据。类型为int, float, reference和returnAddress的值
在数组中占据一项,而类型为byte, short和char的值在存入数组前都被转换为int值,也占据一项。但类型为long和double的值
在数组中却占据连续的两项。

操作数栈

和局部变量区一样,操作数栈也是被组织成一个以字长为单位的数组。它通过标准的栈操作访问–压栈和出栈。由于程序计数器
无法被程序指令直接访问,Java虚拟机的指令是从操作数栈中取得操作数,所以它的运行方式是基于栈而不是基于寄存器。
虚拟机把操作数栈作为它的工作区,因为大多数指令都要从这里弹出数据,执行运算,然后把结果压回操作数栈。

帧数据区

除了局部变量区和操作数栈,Java栈帧还需要帧数据区来支持常量池解析、正常方法返回以及异常派发机制。
每当虚拟机要执行某个需要用到常量池数据的指令时,它会通过帧数据区中指向常量池的指针来访问它。除了常量池的解析外,
帧数据区还要帮助虚拟机处理Java方法的正常结束或异常中止。如果通过return正常结束,虚拟机必须恢复发起调用的方法的
栈帧,包括设置程序计数器指向发起调用方法的下一个指令;如果方法有返回值,虚拟机需要将它压入到发起调用的方法的操作数栈。
为了处理Java方法执行期间的异常退出情况,帧数据区还保存一个对此方法异常表的引用。

本地方法栈

任何本地方法接口都会使用某种本地方法栈,本地方法栈与Java虚拟机栈发挥的作用类似。当线程调用Java方法时,
虚拟机会创建一个新的栈帧并压入Java栈。当它调用的是本地方法时,虚拟机会保持Java栈不变,不再在线程的Java栈中压入新
的栈,虚拟机只是简单地动态连接并直接调用指定的本地方法。

堆(Heap)

Java程序在运行时创建的所有类实例或数组(数组在Java虚拟机中是一个真正的对象)都放在同一个堆中,堆是虚拟机管理的
内存最大的一块,被所有线程所共享,在虚拟机启动的时候创建。堆内存的唯一目的就是存放对象实例,几乎所有的对象实例
都在堆中分配内存。(大对象)

方法区(Method Area)

方法区同Java堆一样,是各个线程共享的内存区域,用于存储已经被虚拟机加载的类信息,常量,静态变量以及
及时编译器(JIT)编译后的代码等信息。

当虚拟机装载某个类型时,它使用类装载器定位相应的class文件,然后读入这个class文件并将它传输到虚拟机中,接着虚拟机
提取其中的类型信息,并将这些信息存储到方法区。方法区也可以被垃圾回收器收集,因为虚拟机允许通过用户定义的类装载器
来动态扩展Java程序。

方法区中存放了以下信息:

• 这个类型的全限定名(如全限定名java.lang.Object)
• 这个类型的直接超类的全限定名
• 这个类型是类类型还是接口类型
• 这个类型的访问修饰符(public, abstract, final的某个子集)
• 任何直接超接口的全限定名的有序列表
• 该类型的常量池,Class文件中除了有类的版本,字段,方法,接口等描述信息外,还有一项是常量池,用于存放编译时生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放
• 字段信息(字段名、类型、修饰符)
• 方法信息(方法名、返回类型、参数数量和类型、修饰符)
• 除了常量以外的所有类(静态)变量
• 指向ClassLoader类的引用(每个类型被装载时,虚拟机必须跟踪它是由启动类装载器还是由用户自定义类装载器装载的)
• 指向Class类的引用(对于每一个被装载的类型,虚拟机相应地为它创建一个java.lang.Class类的实例存于堆中。比如你有一个到java.lang.Integer类的对象的引用,那么只需要调用Integer对象引用的getClass()方法,就可以得到表示java.lang.Integer类的Class对象)

类加载子系统

虚拟机把Java描述类的信息加载到内存,并对数据进行校验,转换解析和初始化,形成可以被Java虚拟机直接使用的Java类型,这就是Java虚拟机的类加载机制。类从加载到虚拟机开始,到卸载出内存为止,它的整个生命周期包括:

加载,验证,准备,解析,初始化,使用和卸载7个阶段。

image

加载

加载是类加载的一个阶段,在该阶段,Java虚拟机主要完成以下三件事情:

• 根据此类的全限定名来确定该类的二进制字节流;
• 将这个字节流所代表的静态数据存储结构转换为方法区的运行时数据结构;
• 在堆内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

验证

验证是连接的第一步,这一阶段的目的是为了确保Class文件的字节流中包含的信息是否符合该虚拟机的要求。

准备

准备阶段正式为类变量在方法区中分配内存并且赋初始值,初始值一般为该类变量类型的零值。

解析

解析阶段虚拟机将常量池内的符号引用替换为直接引用。
符号引用:以一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能无歧义的定位到目标即可。
直接引用:是指能直接指向目标的指针,相对偏移量或是一个能间接定位到目标的句柄。

初始化

初始化是类加载过程的最后一个阶段,在前面的类加载过程中,除了在加载阶段用户可以自定义类加载器参与之外,其余动作完全由虚拟机主导和控制,到了初始化阶段,才真正开始执行类中定义的Java代码(字节码)。准备阶段为类变量分配内存并且赋初始值,赋值操作在初始化阶段执行。

Git 远程仓库

Git 远程仓库

为了能在任意 Git 项目上协作,你需要知道如何管理自己的远程仓库。远程仓库是指托管在因特网或其他网络中的你的项目的版本库。你可以有好几个远程仓库,通常有些仓库对你只读,有些则可以读写。 与他人协作涉及管理远程仓库以及根据需要推送或拉取数据。管理远程仓库包括了解如何添加远程仓库、移除无效的远程仓库、管理不同的远程分支并定义它们是否被跟踪等等。

查看远程仓库

如果想查看你已经配置的远程仓库服务器,可以运行 git remote 命令。 它会列出你指定的每一个远程服务器的简写。 如果你已经克隆了自己的仓库,那么至少应该能看到 origin - 这是 Git 给你克隆的仓库服务器的默认名字:

1
2
3
4
5
6
7
8
9
10
$ git clone git@172.16.5.77:shengwangzhong/storelcoator.git
Cloning into 'storelcoator'...
remote: Reusing existing pack: 1857, done.
remote: Total 1857 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (1857/1857), 374.35 KiB | 268.00 KiB/s, done.
Resolving deltas: 100% (772/772), done.
Checking connectivity... done.
$ cd storelcoator
$ git remote
origin

你也可以指定选项 -v,会显示需要读写远程仓库使用的 Git 保存的简写与其对应的 URL。

1
2
3
$ git remote -v
origin git@172.16.5.77:shengwangzhong/vue-myblog.git (fetch)
origin git@172.16.5.77:shengwangzhong/vue-myblog.git (push)

如果你的远程仓库不止一个,该命令会将它们全部列出。 例如,与几个协作者合作的,拥有多个远程仓库的仓库看起来像下面这样:

1
2
3
4
5
6
7
8
9
10
11
12
$ cd grit
$ git remote -v
bakkdoor https://github.com/bakkdoor/grit (fetch)
bakkdoor https://github.com/bakkdoor/grit (push)
cho45 https://github.com/cho45/grit (fetch)
cho45 https://github.com/cho45/grit (push)
defunkt https://github.com/defunkt/grit (fetch)
defunkt https://github.com/defunkt/grit (push)
koke git://github.com/koke/grit.git (fetch)
koke git://github.com/koke/grit.git (push)
origin git@github.com:mojombo/grit.git (fetch)
origin git@github.com:mojombo/grit.git (push)

添加远程仓库

运行 git remote add 添加一个新的远程 Git 仓库,同时指定一个你可以轻松引用的简写:

1
2
3
4
5
6
7
8
$ git remote
origin
$ git remote add pb https://github.com/paulboone/ticgit
$ git remote -v
origin https://github.com/schacon/ticgit (fetch)
origin https://github.com/schacon/ticgit (push)
pb https://github.com/paulboone/ticgit (fetch)
pb https://github.com/paulboone/ticgit (push)

现在你可以在命令行中使用字符串 pb 来代替整个 URL。 例如,如果你想拉取 Paul 的仓库中有但你没有的信息,可以运行 git fetch pb:

1
2
3
4
5
6
7
8
$ git fetch pb
remote: Counting objects: 43, done.
remote: Compressing objects: 100% (36/36), done.
remote: Total 43 (delta 10), reused 31 (delta 5)
Unpacking objects: 100% (43/43), done.
From https://github.com/paulboone/ticgit
* [new branch] master -> pb/master
* [new branch] ticgit -> pb/ticgit

现在 Paul 的 master 分支可以在本地通过 pb/master 访问到 - 你可以将它合并到自己的某个分支中,或者如果你想要查看它的话,可以检出一个指向该点的本地分支。

从远程仓库中抓取与拉取

就如刚才所见,从远程仓库中获得数据,可以执行:

1
$ git fetch [remote-name]

这个命令会访问远程仓库,从中拉取所有你还没有的数据。 执行完成后,你将会拥有那个远程仓库中所有分支的引用,可以随时合并或查看。

如果你使用 clone 命令克隆了一个仓库,命令会自动将其添加为远程仓库并默认以 “origin” 为简写。 所以,git fetch origin 会抓取克隆(或上一次抓取)后新推送的所有工作。 必须注意 git fetch 命令会将数据拉取到你的本地仓库 - 它并不会自动合并或修改你当前的工作。 当准备好时你必须手动将其合并入你的工作。

如果你有一个分支设置为跟踪一个远程分支,可以使用 git pull 命令来自动的抓取然后合并远程分支到当前分支。这对你来说可能是一个更简单或更舒服的工作流程;==默认情况下,git clone 命令会自动设置本地 master 分支跟踪克隆的远程仓库的 master 分支(或不管是什么名字的默认分支)。== 运行 git pull 通常会从最初克隆的服务器上抓取数据并自动尝试合并到当前所在的分支。

推送到远程仓库

当你想分享你的项目时,必须将其推送到上游。 这个命令很简单:git push [remote-name] [branch-name]。 当你想要将 master 分支推送到 origin 服务器时(再次说明,克隆时通常会自动帮你设置好那两个名字),那么运行这个命令就可以将你所做的备份到服务器:

1
$ git push origin master

只有当你有所克隆服务器的写入权限,并且之前没有人推送过时,这条命令才能生效。 当你和其他人在同一时间克隆,他们先推送到上游然后你再推送到上游,你的推送就会毫无疑问地被拒绝。 你必须先将他们的工作拉取下来并将其合并进你的工作后才能推送。

查看远程仓库(详细)

1
2
3
4
5
6
7
8
9
10
11
$ git remote show origin
* remote origin
Fetch URL: git@172.16.5.77:shengwangzhong/vue-myblog.git
Push URL: git@172.16.5.77:shengwangzhong/vue-myblog.git
HEAD branch: master
Remote branch:
master tracked
Local branch configured for 'git pull':
master merges with remote master
Local ref configured for 'git push':
master pushes to master (up to date)

这个命令列出了当你在特定的分支上执行 git push 会自动地推送到哪一个远程分支。 它也同样地列出了哪些远程分支不在你的本地,哪些远程分支已经从服务器上移除了,还有当你执行 git pull 时哪些分支会自动合并。

远程仓库的移除与重命名

如果想要重命名引用的名字可以运行 git remote rename 去修改一个远程仓库的简写名。 例如,想要将 pb 重命名为 paul,可以用 git remote rename 这样做:

1
2
3
4
$ git remote rename pb paul
$ git remote
origin
paul