After you install Git, configure it for first time use using
git config, a built-in tool that obtains and sets configuration variables. These configuration variables are located in three different places on a GNU/Linux system:
/etc/gitconfig- stores the configuration information for all system users and their respective repositories.
~/.gitconfig- stores user-specific configuration files on the system.
.git/config- this is the configuration file of your current working repository.
For a Windows system, the
.gitconfig file is located in the
$HOME directory of the user’s profile. The full path is
C:\Document and Settings\$USER or
After installing Git make sure your username and email address are set correctly. To verify, use the command:
git config --list
If your name and email are not listed in the output, use the following commands to set them manually, replacing
git config --global user.name examplename git config --global user.email firstname.lastname@example.org
||Add a file to a repository.||
||Remove a file from a repository.||
||Move or rename a tracked file, directory, or symlink.||
||List all the local and remote branches.||
||Commit all staged objects.||
||Download all changes from the remote repo and merge them in a specified repo file.||
||Publish the changes to the remote repo.||
Branches are used for editing files without disturbing the working portions of a project. The main branch is normally named
master, it’s customary to name the branch after an issue being fixed or a feature being implemented. Because Git keep tracks of file changes, you can jump from branch to branch without overwriting or interfering with other branches in the repo.
The basic options used with the
git branch command are:
|-r||List the remote branches|
|-a||Show both local and remote branches|
|-m||Rename an old branch|
|-d||Delete a branch|
|-r -d||Delete a remote branch|
Remote repositories are hosted on a network or another location on the Internet.
||Add a new remote repository.|
||Gather all the data from a remote project that you do not have yet.|
||Obtain and merge a remote branch into your current branch.|
||Move your data from your branch to your server.|
||Display information about the remote you specified.|
||Rename a remote.|
||Remove the remote you specified.|
Like many other Version Control Systems, Git has a way to fire off custom scripts when certain important actions occur. There are two groups of these hooks: client-side and server-side. Client-side hooks are triggered by operations such as committing and merging, while server-side hooks run on network operations such as receiving pushed commits. You can use these hooks for all sorts of reasons.
Installing a Hook
The hooks are all stored in the
hooks subdirectory of the Git directory. In most projects, that’s
.git/hooks. When you initialize a new repository with
git init, Git populates the hooks directory with a bunch of example scripts, many of which are useful by themselves; but they also document the input values of each script. All the examples are written as shell scripts, with some Perl thrown in, but any properly named executable scripts will work fine – you can write them in Ruby or Python or whatever language you are familiar with. If you want to use the bundled hook scripts, you’ll have to rename them; their file names all end with
To enable a hook script, put a file in the
hooks subdirectory of your .git directory that is named appropriately (without any extension) and is executable. From that point forward, it should be called. We’ll cover most of the major hook filenames here.
There are a lot of client-side hooks. This section splits them into committing-workflow hooks, email-workflow scripts, and everything else.
|Note||It’s important to note that client-side hooks are not copied when you clone a repository. If your intent with these scripts is to enforce a policy, you’ll probably want to do that on the server side; see the example in An Example Git-Enforced Policy.|
The first four hooks have to do with the committing process.
pre-commit hook is run first, before you even type in a commit message. It’s used to inspect the snapshot that’s about to be committed, to see if you’ve forgotten something, to make sure tests run, or to examine whatever you need to inspect in the code. Exiting non-zero from this hook aborts the commit, although you can bypass it with
git commit --no-verify. You can do things like check for code style (run
lint or something equivalent), check for trailing whitespace (the default hook does exactly this), or check for appropriate documentation on new methods.
prepare-commit-msg hook is run before the commit message editor is fired up but after the default message is created. It lets you edit the default message before the commit author sees it. This hook takes a few parameters: the path to the file that holds the commit message so far, the type of commit, and the commit SHA-1 if this is an amended commit. This hook generally isn’t useful for normal commits; rather, it’s good for commits where the default message is auto-generated, such as templated commit messages, merge commits, squashed commits, and amended commits. You may use it in conjunction with a commit template to programmatically insert information.
commit-msg hook takes one parameter, which again is the path to a temporary file that contains the commit message written by the developer. If this script exits non-zero, Git aborts the commit process, so you can use it to validate your project state or commit message before allowing a commit to go through. In the last section of this chapter, We’ll demonstrate using this hook to check that your commit message is conformant to a required pattern.
After the entire commit process is completed, the
post-commit hook runs. It doesn’t take any parameters, but you can easily get the last commit by running
git log -1 HEAD. Generally, this script is used for notification or something similar.
Email Workflow Hooks
You can set up three client-side hooks for an email-based workflow. They’re all invoked by the
git am command, so if you aren’t using that command in your workflow, you can safely skip to the next section. If you’re taking patches over email prepared by
git format-patch, then some of these may be helpful to you.
The first hook that is run is
applypatch-msg. It takes a single argument: the name of the temporary file that contains the proposed commit message. Git aborts the patch if this script exits non-zero. You can use this to make sure a commit message is properly formatted, or to normalize the message by having the script edit it in place.
The next hook to run when applying patches via
git am is
pre-applypatch. Somewhat confusingly, it is run after the patch is applied but before a commit is made, so you can use it to inspect the snapshot before making the commit. You can run tests or otherwise inspect the working tree with this script. If something is missing or the tests don’t pass, exiting non-zero aborts the
git amscript without committing the patch.
The last hook to run during a
git am operation is
post-applypatch, which runs after the commit is made. You can use it to notify a group or the author of the patch you pulled in that you’ve done so. You can’t stop the patching process with this script.
Other Client Hooks
pre-rebase hook runs before you rebase anything and can halt the process by exiting non-zero. You can use this hook to disallow rebasing any commits that have already been pushed. The example
pre-rebase hook that Git installs does this, although it makes some assumptions that may not match with your workflow.
post-rewrite hook is run by commands that replace commits, such as
git commit --amendand
git rebase (though not by
git filter-branch). Its single argument is which command triggered the rewrite, and it receives a list of rewrites on
stdin. This hook has many of the same uses as the
After you run a successful
git checkout, the
post-checkout hook runs; you can use it to set up your working directory properly for your project environment. This may mean moving in large binary files that you don’t want source controlled, auto-generating documentation, or something along those lines.
post-merge hook runs after a successful
merge command. You can use it to restore data in the working tree that Git can’t track, such as permissions data. This hook can likewise validate the presence of files external to Git control that you may want copied in when the working tree changes.
pre-push hook runs during
git push, after the remote refs have been updated but before any objects have been transferred. It receives the name and location of the remote as parameters, and a list of to-be-updated refs through
stdin. You can use it to validate a set of ref updates before a push occurs (a non-zero exit code will abort the push).
Git occasionally does garbage collection as part of its normal operation, by invoking
git gc --auto. The
pre-auto-gc hook is invoked just before the garbage collection takes place, and can be used to notify you that this is happening, or to abort the collection if now isn’t a good time.
In addition to the client-side hooks, you can use a couple of important server-side hooks as a system administrator to enforce nearly any kind of policy for your project. These scripts run before and after pushes to the server. The pre hooks can exit non-zero at any time to reject the push as well as print an error message back to the client; you can set up a push policy that’s as complex as you wish.
The first script to run when handling a push from a client is
pre-receive. It takes a list of references that are being pushed from stdin; if it exits non-zero, none of them are accepted. You can use this hook to do things like make sure none of the updated references are non-fast-forwards, or to do access control for all the refs and files they’re modifying with the push.
update script is very similar to the
pre-receive script, except that it’s run once for each branch the pusher is trying to update. If the pusher is trying to push to multiple branches,
pre-receive runs only once, whereas update runs once per branch they’re pushing to. Instead of reading from stdin, this script takes three arguments: the name of the reference (branch), the SHA-1 that reference pointed to before the push, and the SHA-1 the user is trying to push. If the update script exits non-zero, only that reference is rejected; other references can still be updated.
post-receive hook runs after the entire process is completed and can be used to update other services or notify users. It takes the same stdin data as the
pre-receive hook. Examples include emailing a list, notifying a continuous integration server, or updating a ticket-tracking system – you can even parse the commit messages to see if any tickets need to be opened, modified, or closed. This script can’t stop the push process, but the client doesn’t disconnect until it has completed, so be careful if you try to do anything that may take a long time.
利用 Git Hooks 完成本地测试环境的启动以及生成环境的部署
不重复的引用公共资源 gti submodule
Github’s Git Handbook
What’s a version control system?
A version control system, or VCS, tracks the history of changes as people and teams collaborate on projects together. As the project evolves, teams can run tests, fix bugs, and contribute new code with the confidence that any version can be recovered at any time. Developers can review project history to find out:
- Which changes were made?
- Who made the changes?
- When were the changes made?
- Why were changes needed?
What’s a distributed version control system?
Git is an example of a distributed version control system (DVCS) commonly used for open source and commercial software development. DVCSs allow full access to every file, branch, and iteration of a project, and allows every user access to a full and self-contained history of all changes. Unlike once popular centralized version control systems, DVCSs like Git don’t need a constant connection to a central repository. Developers can work anywhere and collaborate asynchronously from any time zone.
What’s a repository?
A repository, or Git project, encompasses the entire collection of files and folders associated with a project, along with each file’s revision history. The file history appears as snapshots in time called commits, and the commits exist as a linked-list relationship, and can be organized into multiple lines of development called branches. Because Git is a DVCS, repositories are self-contained units and anyone who owns a copy of the repository can access the entire codebase and its history. Using the command line or other ease-of-use interfaces, a git repository also allows for: interaction with the history, cloning, creating branches, committing, merging, comparing changes across versions of code, and more.
Working in repositories keeps development projects organized and protected. Developers are encouraged to fix bugs, or create fresh features, without fear of derailing mainline development efforts. Git facilitates this through the use of topic branches: lightweight pointers to commits in history that can be easily created and deprecated when no longer needed.
Through platforms like GitHub, Git also provides more opportunities for project transparency and collaboration. Public repositories help teams work together to build the best possible final product.
Basic Git commands
To use Git, developers use specific commands to copy, create, change, and combine code. These commands can be executed directly from the command line or by using an application like GitHub Desktop or Git Kraken. Here are some common commands for using Git:
git initinitializes a brand new Git repository and begins tracking an existing directory. It adds a hidden subfolder within the existing directory that houses the internal data structure required for version control.
git clonecreates a local copy of a project that already exists remotely. The clone includes all the project’s files, history, and branches.
git addstages a change. Git tracks changes to a developer’s codebase, but it’s necessary to stage and take a snapshot of the changes to include them in the project’s history. This command performs staging, the first part of that two-step process. Any changes that are staged will become a part of the next snapshot and a part of the project’s history. Staging and committing separately gives developers complete control over the history of their project without changing how they code and work.
git commitsaves the snapshot to the project history and completes the change-tracking process. In short, a commit functions like taking a photo. Anything that’s been staged with
git addwill become a part of the snapshot with
git statusshows the status of changes as untracked, modified, or staged.
git branchshows the branches being worked on locally.
git mergemerges lines of development together. This command is typically used to combine changes made on two distinct branches. For example, a developer would merge when they want to combine changes from a feature branch into the master branch for deployment.
git pullupdates the local line of development with updates from its remote counterpart. Developers use this command if a teammate has made commits to a branch on a remote, and they would like to reflect those changes in their local environment.
git pushupdates the remote repository with any commits made locally to a branch.
How GitHub works
GitHub builds collaboration directly into the developement process. Work is organized into repositories, where devlopers can outlines requirements or direction and set expectations for team members. Then, using the GitHub flow, developers simply create a branch to work on updates, commit changes to save them, open a pull request to propose and discuss changes, and merge pull requests once everyone is on the same page.
The GitHub flow
The GitHub flow is a lightweight, branch-based workflow built around core Git commands used by teams around the globe—including ours.
The GitHub flow has six steps, each with distinct benefits when implemented:
- Create a branch: Topic branches created from the canonical deployment branch (usually
master) allow teams to contribute to many parallel efforts. Short-lived topic branches, in particular, keep teams focused and results in quick ships.
- Add commits: Snapshots of development efforts within a branch create safe, revertible points in the project’s history.
- Open a pull request: Pull requests publicize a project’s ongoing efforts and set the tone for a transparent development process.
- Discuss and review code: Teams participate in code reviews by commenting, testing, and reviewing open pull requests. Code review is at the core of an open and participatory culture.
- Merge: Upon clicking merge, GitHub automatically performs the equivalent of a local ‘git merge’ operation. GitHub also keeps the entire branch development history on the merged pull request.
- Deploy: Teams can choose the best release cycles or incorporate continuous integration tools and operate with the assurance that code on the deployment branch has gone through a robust workflow.
The ways of GitHub for collaborative development
There are two primary ways people collaborate on GitHub:
With a shared repository, individuals and teams are explicitly designated as contributors with read, write, or administrator access. This simple permission structure, combined with features like protected branches and Marketplace, helps teams progress quickly when they adopt GitHub.
For an open source project, or for projects to which anyone can contribute, managing individual permissions can be challenging, but a fork and pull model allows anyone who can view the project to contribute. A fork is a copy of a project under an developer’s personal account. Every developer has full control of their fork and is free to implement a fix or new feature. Work completed in forks is either kept separate, or is surfaced back to the original project via a pull request. There, maintainers can review the suggested changes before they’re merged.
After using GitHub by yourself for a while, you may find yourself wanting to contribute to someone else’s project. Or maybe you’d like to use someone’s project as the starting point for your own. This process is known as forking.
Creating a “fork” is producing a personal copy of someone else’s project. Forks act as a sort of bridge between the original repository and your personal copy. You can submit Pull Requests to help make other people’s projects better by offering your changes up to the original project.
Fork -> Clone -> Add and Commit the changes -> Push to remote
It’s important to provide as much useful information and a rationale for why you’re making this Pull Request in the first place. The project owner needs to be able to determine whether your change is as useful to everyone as you think it is.
Pull Requests are an area for discussion. For projects, don’t be offended if the project owner rejects your Pull Request, or asks for more information on why it’s been made. It may even be that the project owner chooses not to merge your pull request, and that’s totally okay. Your copy will exist in infamy on the Internet. And who knows–maybe someone you’ve never met will find your changes much more valuable than the original project. Share and share alike!