Setting Up A Repository: Git Init
Setting Up A Repository: Git Init
The place where you do your actual work. It contains tracked files, untracked files and a special directory .git.
Index/Staging area
It is used for preparing commits. You can add files to the next commit or even only parts of files for the next commit.
All the changes youd like to commit get into the index/stating-area first.
HEAD
HEAD is, normally, a symbolic reference to [the tip of] a branch. It is a reference to the last commit in the current
checked out branch.
detached HEAD
Any checkout of a commit that is not the name of one of your branches will get you a detached HEAD. A SHA1 which
represents the tip of a branch would still gives a detached HEAD. Only a checkout of a local branch name avoids that
mode.
Branch
A single repository can track an arbitrary number of branches, but your working tree is associated with just one of
them (the "current" or "checked out" branch), and HEAD points to that branch.
Setting up a repository
git init
It is used to initialize a repository.
It creates a .git subdirectory in the project root, which contains all of the necessary metadata for the repository
git init
Running this command will also create a new folder called <directory>
Usually, the central repository is bare, and developers local repositories are non-bare.
git clone
It is used to clone the repository located at <repo> onto the local machine.
Clone the repository located at <repo> into the folder called <directory> on the local machine
Define the author name, email to be used for all commits in the current repository and the --global flag is used to set
configuration options for the current user.
Saving changes
git add
It adds a change in the working directory to the staging area.
when -A option is used, all files in the entire working tree are updated
git add -A
Begin an interactive staging session that lets us choose portions of a file to add to the staging area
git commit
It commits the staged snapshot to the repository
git commit
It commits the staged snapshot, but use <message> as the commit message
git commit -m "<message>"
It commits the snapshot of all changes in the working directory. This only includes modifications to tracked files
(those that have been added with git add at some point in their history).
git commit -a
git diff
To get the diff of our HEAD vs the workspace
git diff
Tip: If you're having a hard time summarizing, you might be committing too many changes at once. Strive for atomic
commits
As if you were commanding someone. Write "fix", "add", "change" instead of "fixed", "added", "changed".
e.g.
https://robinpowered.com/blog/best-practice-system-for-organizing-and-tagging-github-issues/
http://modeling-languages.com/use-of-issue-labels-in-github/
http://radek.io/2015/08/24/github-issues/
https://docs.saltstack.com/en/latest/topics/development/labels.html
https://mediocre.com/forum/topics/how-we-use-labels-on-github-issues-at-mediocre-laboratories
Revert
If the commit reverts a previous commit, it should begin with revert:, followed by the header of the reverted
commit. In the body it should say: This reverts commit <hash>., where the hash is the SHA of the commit being
reverted.
Type
feat: A new feature
fix: A bug fix
docs: Documentation only changes
style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons,
etc)
refactor: A code change that neither fixes a bug nor adds a feature
perf: A code change that improves performance
test: Adding missing tests
chore: Changes to the build process or auxiliary tools and libraries such as documentation generation
Atomic Approach
1. Commit each fix or task as a separate change
2. Only commit when a block of work is complete
3. Commit each layout change separately
4. Joint commit for layout file, code behind file, and additional resources
Benefits
1. Easy to roll back without affecting other changes
2. Easy to make other changes on the fly
3. Easy to merge features to other branches
Inspecting a repository
git status
It lists which files are staged, unstaged, and untracked.
Git lets you completely ignore files by placing paths in a special file called .gitignore. Any files that you'd like to
ignore should be included on a separate line, and the * symbol can be used as a wildcard.
git log
Display the entire commit history using the default formatting.
If the output takes up more than one screen, you can use Space to scroll and q to exit.
Along with the log information, include which files were altered and the relative number of lines that were added or
deleted from each of them.
Checking out a commit makes the entire working directory match that commit.
To switch to the <branch> branch by updating the staging area, the work space, and by pointing HEAD at the
<branch>
To update all files in the working directory to match the specified commit.
You can use either a commit hash or a tag as the <commit> argument.
Unlike checking out a commit, this does affect the current state of your project.
The old file revision will show up as a Change to be committed, giving you the opportunity to revert back to the
previous version of the file.
If you dont want to keep the old version, you can check out the most recent version using this command
To discard changes in the workspace. Files can be changed back to how they were at the last commit
git revert
To generate a new commit that undoes all of the changes introduced in <commit> and then apply it to the current
branch.
Instead of removing the commit from the project history, it figures out how to undo the changes introduced by the
commit and appends a new commit with the resulting content
Reverting should be used when you want to remove an entire commit from your project history.
git reset
When you undo with git reset, there is no way to retrieve the original copyit is a permanent undo.
To reset the staging area to match the most recent commit, but leave the working directory unchanged.
git reset
To remove the specified file from the staging area, but leave the working directory unchanged. This unstages a file
without overwriting any changes.
To reset the staging area and the working directory to match the most recent commit
To move the current branch tip backward to <commit>, reset the staging area to match, but leave the working
directory alone.
All changes made since <commit> will reside in the working directory
To move the current branch tip backward to <commit> and reset both the staging area and the working directory to
match.
Note: This obliterates not only the uncommitted changes, but all commits after <commit>
git clean
The git clean command removes untracked files from your working directory.
This is really more of a convenience command, since its trivial to see which files are untracked with git status and
remove them manually.
Remove untracked files from the current directory. The -f (force) flag is to not remove untracked folders or files
specified by .gitignore.
git clean -f
Remove untracked files, but limit the operation to the specified path.
Perform a dry run of git clean. This will show you which files are going to be removed without actually doing it.
git clean -n
Remove untracked files and untracked directories from the current directory.
Remove untracked files from the current directory as well as any files that Git usually ignores.
Rewriting history
git commit --amend
It is a convenient way to fix up the most recent commit.
It combines staged changes with the previous commit instead of committing it as an entirely new snapshot.
Running this when there is nothing staged lets you edit the previous commits message without altering its snapshot.
git rebase
Rebasing is the process of moving a branch to a new base commit.
Even though the branch looks the same, its composed of entirely new commits.
To rebase the current branch onto <base>, which can be any kind of commit reference (an ID, a branch name, a tag,
or a relative reference to HEAD)
git rebase -i
Interactive rebasing can keep a projects history clean and meaningful.
To rebase the current branch onto <base>, but use an interactive rebasing session. This opens an editor where you
can enter commands(pick/squash) for each commit to be rebased.
Note:
Interactive rebasing gives you complete control over what your project history looks like. This affords a lot of
freedom to developers, as it lets them commit a messy history while theyre focused on writing code, then go back
and clean it up after the fact.
Most developers like to use an interactive rebase to polish a feature branch before merging it into the main code
base. This gives them the opportunity to squash insignificant commits, delete obsolete ones, and make sure
everything else is in order before committing to the official project history. To everybody else, it will look like the
entire feature was developed in a single series of well-planned commits.
git reflog
Git keeps track of updates to the tip of branches using a mechanism called reflog. This allows you to go back to
changesets even though they are not referenced by any branch or tag.
git reflog
Note: It's important to note that the reflog only provides a safety net if changes have been commited to your local
repository and that it only tracks movements.
Syncing
git remote
The git remote command lets you create, view, and delete connections to other repositories.
git remote
git remote -v
Note: When you clone a repository with git clone, it automatically creates a remote connection called origin pointing
back to the cloned repository.
git fetch
This command imports commits from a remote repository into your local repo. The resulting commits are stored as
remote branches instead of the normal local branches that weve been working with.
This gives you a chance to review changes before integrating them into your copy of the project.
git pull
To merge upstream changes into your local repository.
We already know how to do this with git fetch followed by git merge, but git pull rolls this into a single command.
To fetch the specified remotes copy of the current branch and immediately merge it into the local copy
This is the same as git fetch <remote> followed by git merge origin/<current-branch>
Instead of using git merge to integrate the remote branch with the local one, using git rebase
git push
It is how you transfer commits from your local repository to a remote repo.
It's the counterpart to git fetch, but whereas fetching imports commits to local branches, pushing exports commits
to remote branches.
To push the specified branch to <remote>, along with all of the necessary commits and internal objects. This creates
a local branch in the destination repository.
Tags are not automatically pushed when you push a branch or use the --all option. The --tags flag sends all of your
local tags to the remote repository.
There is only one public repository in the Feature Branch Workflow, so the pull requests destination repository and
the source repository will always be the same. Typically, the developer will specify their feature branch as the source
branch and the master branch as the destination branch.
After receiving the pull request, the project maintainer has to decide what to do. If the feature is ready to go, they
can simply merge it into master and close the pull request. But, if there are problems with the proposed changes,
they can post feedback in the pull request. Follow-up commits will show up right next to the relevant comments.
Its also possible to file a pull request for a feature that is incomplete. For example, if a developer is having trouble
implementing a particular requirement, they can file a pull request containing their work-in-progress. Other
developers can then provide suggestions inside of the pull request, or even fix the problem themselves with
additional commits.
The mechanics of pull requests in the Gitflow Workflow are the exact same as the previous section: a developer
simply files a pull request when a feature, release, or hotfix branch needs to be reviewed, and the rest of the team
will be notified.
Features are generally merged into the develop branch, while release and hotfix branches are merged into both
develop and master. Pull requests can be used to formally manage all of these merges.
The notification aspect of pull requests is particularly useful in this workflow because the project maintainer has no
way of knowing when another developer has added commits to their repository.
Since each developer has their own public repository, the pull requests source repository will differ from its
destination repository. The source repository is the developers public repository and the source branch is the one
that contains the proposed changes. If the developer is trying to merge the feature into the main codebase, then the
destination repository is the official project and the destination branch is master.
Pull requests can also be used to collaborate with other developers outside of the official project. For example, if a
developer was working on a feature with a teammate, they could file a pull request using the teammates Bitbucket
repository for the destination instead of the official project. They would then use the same feature branch for the
source and destination branches.
The two developers could discuss and develop the feature inside of the pull request. When theyre done, one of
them would file another pull request asking to merge the feature into the official master branch. This kind of
flexibility makes pull requests very powerful collaboration tool in the Forking workflow.
Using Branches
git branch
A branch represents an independent line of development. Branches serve as an abstraction for the
edit/stage/commit process
git checkout
This command lets you navigate between the branches. Checking out a branch updates the files in the working
directory to match the version stored in that branch.
To base the new branch off of <existing-branch> instead of the current branch
git merge