Once you’ve cloned or initialized a new Git project, just start changing files as needed for your current assignment. There is no pessimistic locking of files by teammates. In fact, there’s no locking at all. Git operates in a very optimistic manner, confident that its merge capabilities are a match for any conflicted changes that you and your colleagues can craft.
If you need to move a file, Git can often detect your manual relocation of the file and will show it as a pending “move.” However, it is often more prudent to just directly tell Git to relocate a file and track its new destination.
If you wish to expunge a file from the current state of the branch, simply tell Git to remove it. It will be put in a pending deletion state and can be confirmed and completed by the next commit.
Daily work calls for strong support of viewing current and historical facts about your repository, often from different, perhaps even orthogonal points of view. Git satisfies those demands in spades.
To check the current status of a project’s local directories and files (modified, new, deleted, or untracked) invoke the status command:
A patch-style view of the difference between the currently edited and committed files, or any two points in the past can easily be summoned. The .. operator signifies a range is being provided. An omitted second element in the range implies a destination of the current committed state, also known as HEAD:
Depending on the Git distribution, a utility called diff-highlight will be included to make diffs easier to visualize by highlighting word-level diffs instead of the default line level changes. Make sure diff-highlight is available in your $PATH and enable it with:
Git allows for diffing between the local files, the stage files, and the committed files with a great deal of precision.
||Everything unstaged (not git add’ed) diffed to the last commit
|git diff –cached
||Everything staged (git add’ed) diffed to the last commit
|git diff HEAD
||Everything unstaged and staged diffed to the last commit
The full list of changes since the beginning of time, or optionally, since a certain date is right at your fingertips, even when disconnected from all networks:
If trying to discover why and when a certain line was added, cut to the chase and have Git annotate each line of a source file with the name and date it was last modified:
Git offers a useful feature for those times when your changes are in an incomplete state, you aren’t ready to commit them, and you need to temporarily return to the last committed (e.g. a fresh checkout). This feature is named “stash” and pushes all your uncommitted changes onto a stack.
When you are ready to write the stashed changes back into the working copies of the files, simply pop them back on the stack.
If you want to abort your current uncommitted changes and restore the working copy to the last committed state, there are two commands that will help you accomplish this.Resetting with the hard option recursively discards all your currently uncommitted (unstaged or staged) changes.
To target just one blob, use the checkout command to restore the file to its previous committed state.
When the developer is ready to put files into the next commit, they must be first staged with the add command. Users can navigate to any directory, adding files item by item, or by wildcard.
Specifying a folder name as the target of a git add recursively stages files in any subdirectories.
The -i option activates interactive add mode, in which Git prompts for the files to be added or excluded from the next commit.
The -p option is a shortcut for activation of the patch sub-mode of the interactive prompt, allowing for precise pieces within a file to be selected for staging.
It’s a common use case to need to exclude some files in a project from being tracked by Git. This is supported through a .gitignore file per project that is a list of file/directory patterns to be automatically ignored. More information is available at https://help.github.com/articles/ignoring-files/.
Once all the desired blobs are staged, a commit command transactionally saves the pending additions to the local repository. The default text $EDITOR will be opened for entry of the commit message, if unset vi is the default.
Git requires that a message be present on commits, leaving the message blank will abort the commit and leave the staged blobs in place.
The default editor can be changed with a Git configuration or by setting the $EDITOR environment variable:
To supply the commit message directly at the command prompt:
To view the statistics and facts about the last commit:
If a mistake was made in the last commit’s message, edit the commit text while leaving the changed files as-is with:
Branching superficially appears much the same as it does in other version control systems, but the difference lies in the fact that Git branches can be targeted to exist only locally or be shared with (pushed to) the rest of the team. The concept of inexpensive local branches increases the frequency in which developers use branching, opening it up to use for quick private experiments that may be discarded if unsuccessful, or merged onto a well-known branch if successful.
Choosing a Branch
Checking out (switching to) a branch is as simple as providing its name:
Local and remote branches are checked out using the same command, but in somewhat of a radical change of operation for users coming from other systems like Subversion, remote branches are read-only until “tracked” and copied to a local branch. Local branches are where new work is performed and code is committed.
Or alternatively, in a combined command:
Starting with Git 1.6.6, a shorthand notation can be used to track a remote branch with a local branch of exactly the same name when no local branch of that name already exists and only one remote location is configured.
To list the complete set of current local and remote branches known to Git:
The local branches typically have simple names like master and experiment. Local branches are shown in white by Git’s default syntax highlighting while the currently tracked branch is green with an asterisk prefix. Remote branches are prefixed by “remotes/” and are shown in red.
Like other popular VCSes, Git allows you to merge one or more branches into the current branch.
If any conflicts are encountered, which is rare with Git, a notification message is displayed and the files are internally marked with >>>>>>>>> and <<<<<<<< around the conflicting portion of the file contents. Once manually resolved, git-add the resolved file, then commit in the usual manner.
Rebasing is the rewinding of existing commits on a branch with the intent of moving the “branch start point” forward, then replaying the rewound commits. This allows developers to test their branch changes safely in isolation on their private branch just as if they were made on top of the mainline code, including any recent mainline bug fixes.
Automation with Hooks
Git runs a standard set of hooks during user actions. Users can define custom scripts to be run that could be utilized to interrupt actions for code quality, spell checking, testing, etc. There are samples pre-installed in .git/hooks, details are available in the Git book: https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks