-
1. Untuk Bermula
-
2. Git Basics
- 2.1 Mendapatkan suatu Repositori Git
- 2.2 Merekodkan Perubahan bagi Repositori
- 2.3 Viewing the Commit History
- 2.4 Undoing Things
- 2.5 Working with Remotes
- 2.6 Tagging
- 2.7 Alias Git
- 2.8 Summary
-
3. Git Branching
- 3.1 Branches in a Nutshell
- 3.2 Basic Branching and Merging
- 3.3 Branch Management
- 3.4 Branching Workflows
- 3.5 Remote Branches
- 3.6 Rebasing
- 3.7 Summary
-
4. Git on the Server
- 4.1 The Protocols
- 4.2 Getting Git on a Server
- 4.3 Generating Your SSH Public Key
- 4.4 Setting Up the Server
- 4.5 Git Daemon
- 4.6 Smart HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Third Party Hosted Options
- 4.10 Summary
-
5. Distributed Git
- 5.1 Distributed Workflows
- 5.2 Contributing to a Project
- 5.3 Maintaining a Project
- 5.4 Summary
-
6. GitHub
-
7. Git Tools
- 7.1 Revision Selection
- 7.2 Interactive Staging
- 7.3 Stashing and Cleaning
- 7.4 Signing Your Work
- 7.5 Searching
- 7.6 Rewriting History
- 7.7 Reset Demystified
- 7.8 Advanced Merging
- 7.9 Rerere
- 7.10 Debugging with Git
- 7.11 Submodules
- 7.12 Bundling
- 7.13 Replace
- 7.14 Credential Storage
- 7.15 Summary
-
8. Customizing Git
- 8.1 Git Configuration
- 8.2 Git Attributes
- 8.3 Git Hooks
- 8.4 An Example Git-Enforced Policy
- 8.5 Summary
-
9. Git and Other Systems
- 9.1 Git as a Client
- 9.2 Migrating to Git
- 9.3 Summary
-
10. Git Internals
- 10.1 Plumbing and Porcelain
- 10.2 Git Objects
- 10.3 Git References
- 10.4 Packfiles
- 10.5 The Refspec
- 10.6 Transfer Protocols
- 10.7 Maintenance and Data Recovery
- 10.8 Environment Variables
- 10.9 Summary
-
A1. Appendix A: Git in Other Environments
- A1.1 Graphical Interfaces
- A1.2 Git in Visual Studio
- A1.3 Git in Eclipse
- A1.4 Git in Bash
- A1.5 Git in Zsh
- A1.6 Git in Powershell
- A1.7 Summary
-
A2. Appendix B: Embedding Git in your Applications
- A2.1 Command-line Git
- A2.2 Libgit2
- A2.3 JGit
-
A3. Appendix C: Git Commands
- A3.1 Setup and Config
- A3.2 Getting and Creating Projects
- A3.3 Basic Snapshotting
- A3.4 Branching and Merging
- A3.5 Sharing and Updating Projects
- A3.6 Inspection and Comparison
- A3.7 Debugging
- A3.8 Patching
- A3.9 Email
- A3.10 External Systems
- A3.11 Administration
- A3.12 Plumbing Commands
10.5 Git Internals - The Refspec
The Refspec
Throughout this book, we’ve used simple mappings from remote branches to local references, but they can be more complex. Suppose you were following along with the last couple sections and had created a small local Git repository, and now wanted to add a remote to it:
$ git remote add origin https://github.com/schacon/simplegit-progit
Running the command above adds a section to your repository’s .git/config
file, specifying the name of the remote (origin
), the URL of the remote repository, and the refspec to be used for fetching:
[remote "origin"]
url = https://github.com/schacon/simplegit-progit
fetch = +refs/heads/*:refs/remotes/origin/*
The format of the refspec is, first, an optional +
, followed by <src>:<dst>
, where <src>
is the pattern for references on the remote side and <dst>
is where those references will be tracked locally.
The +
tells Git to update the reference even if it isn’t a fast-forward.
In the default case that is automatically written by a git remote add
command, Git fetches all the references under refs/heads/
on the server and writes them to refs/remotes/origin/
locally.
So, if there is a master
branch on the server, you can access the log of that branch locally via any of the following:
$ git log origin/master
$ git log remotes/origin/master
$ git log refs/remotes/origin/master
They’re all equivalent, because Git expands each of them to refs/remotes/origin/master
.
If you want Git instead to pull down only the master
branch each time, and not every other branch on the remote server, you can change the fetch line to refer to that branch only:
fetch = +refs/heads/master:refs/remotes/origin/master
This is just the default refspec for git fetch
for that remote.
If you want to do a one-time only fetch, you can specify the specific refspec on the command line, too.
To pull the master
branch on the remote down to origin/mymaster
locally, you can run:
$ git fetch origin master:refs/remotes/origin/mymaster
You can also specify multiple refspecs. On the command line, you can pull down several branches like so:
$ git fetch origin master:refs/remotes/origin/mymaster \
topic:refs/remotes/origin/topic
From git@github.com:schacon/simplegit
! [rejected] master -> origin/mymaster (non fast forward)
* [new branch] topic -> origin/topic
In this case, the master
branch pull was rejected because it wasn’t listed as a fast-forward reference.
You can override that by specifying the +
in front of the refspec.
You can also specify multiple refspecs for fetching in your configuration file.
If you want to always fetch the master
and experiment
branches from the origin
remote, add two lines:
[remote "origin"]
url = https://github.com/schacon/simplegit-progit
fetch = +refs/heads/master:refs/remotes/origin/master
fetch = +refs/heads/experiment:refs/remotes/origin/experiment
You can’t use partial globs in the pattern, so this would be invalid:
fetch = +refs/heads/qa*:refs/remotes/origin/qa*
However, you can use namespaces (or directories) to accomplish something like that.
If you have a QA team that pushes a series of branches, and you want to get the master
branch and any of the QA team’s branches but nothing else, you can use a config section like this:
[remote "origin"]
url = https://github.com/schacon/simplegit-progit
fetch = +refs/heads/master:refs/remotes/origin/master
fetch = +refs/heads/qa/*:refs/remotes/origin/qa/*
If you have a complex workflow process that has a QA team pushing branches, developers pushing branches, and integration teams pushing and collaborating on remote branches, you can namespace them easily this way.
Pushing Refspecs
It’s nice that you can fetch namespaced references that way, but how does the QA team get their branches into a qa/
namespace in the first place?
You accomplish that by using refspecs to push.
If the QA team wants to push their master
branch to qa/master
on the remote server, they can run
$ git push origin master:refs/heads/qa/master
If they want Git to do that automatically each time they run git push origin
, they can add a push
value to their config file:
[remote "origin"]
url = https://github.com/schacon/simplegit-progit
fetch = +refs/heads/*:refs/remotes/origin/*
push = refs/heads/master:refs/heads/qa/master
Again, this will cause a git push origin
to push the local master
branch to the remote qa/master
branch by default.
Deleting References
You can also use the refspec to delete references from the remote server by running something like this:
$ git push origin :topic
Because the refspec is <src>:<dst>
, by leaving off the <src>
part, this basically says to make the topic
branch on the remote nothing, which deletes it.
Or you can use the newer syntax (available since Git v1.7.0):
$ git push origin --delete topic