Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Make room for this example
- if [[ -d /tmp/git-example ]]; then
- rm -rf /tmp/git-example
- fi
- # Start Here
- mkdir -p /tmp/git-example
- cd /tmp/git-example
- # This will be the equivalent to the user's fork on github
- # This will be the first user
- mkdir user0
- cd user0 && git init && cd ..
- USER0="user0 <user0@localhost>"
- # This will be the second user
- mkdir user1
- cd user1 && git init && cd ..
- USER1="user1 <user1@localhost>"
- # Now we need to make two repo's that will act as the github equivalent to a local user's fork
- mkdir user0-repo
- cd user0-repo && git init --bare && cd ..
- mkdir user1-repo
- cd user1-repo && git init --bare && cd ..
- # Make another repo to represent the github ooi repository
- mkdir upstream
- cd upstream && git init --bare && cd ..
- # user0 will initialize the project with a README
- cd user0
- cat << EOF > README.md
- An empty README file, this is only used for
- example purposes.
- EOF
- git add README.md
- git commit -m "Initial Commit with README" --author $USER0
- # Add the origin (user fork)
- git remote add origin /tmp/git-example/user0-repo
- # Add the upstream (ooici repo)
- git remote add upstream /tmp/git-example/upstream
- # Initialize the repo by making a new branch "master"
- git push origin master
- # Initialize upstream by making a new branch "master"
- git push upstream master
- # Make a new branch REL2.0
- git checkout -B REL2.0
- # Push the branch to the two repos
- git push origin REL2.0
- git push upstream REL2.0
- # Back to the master branch
- git checkout master
- #--------------------------------------------------------------------------------
- # user0 is going to do some standard work and push to the repos directly
- # this is not recommended but just shows what happens
- #--------------------------------------------------------------------------------
- cat << EOF > hello.py
- def hello():
- print "Hello, World!"
- if __name__ == '__main__':
- hello()
- EOF
- # git-add saves the changes or adds the new file to the git-filesystem. Git objects are whole files
- # (not diffs, contrary to popular belief) and the name of the file is a SHA1 hash of the file contents and a unique
- # string to git
- git add hello.py
- # If we run git-status we can see that the file is "staged" to be committed. Staged files are git-objects that are new
- # to the git file-system and are flagged to be saved if the changes are committed.
- git status
- #------------- OUTPUT ---------------------------------------------------------
- #
- # On branch master
- # Changes to be committed:
- # (use "git reset HEAD <file>..." to unstage)
- #
- # new file: hello.py
- #
- #--------------------------------------------------------------------------------
- # We can save our work thus far by committing it, a commit is the sha1 hash of a git tree-object which contains a list
- # of the git-objects it points at. We can look at our current tree's files with the git cat-file command
- git cat-file -p master\^{tree}
- #------------- OUTPUT ---------------------------------------------------------
- # 100644 blob d2617a67f7fd50e85356270658ac6531f7d24bb5 README.md
- #--------------------------------------------------------------------------------
- # Now we commit our work which generates a new tree object and the commit sha is the SHA1 hash of that tree object that
- # now has our new file in it.
- git commit -m "Added hello.py" --author $USER0
- #------------- OUTPUT ---------------------------------------------------------
- #[master 4738aa0] Added hello.py
- # 1 file changed, 4 insertions(+)
- # create mode 100644 hello.py
- #--------------------------------------------------------------------------------
- # Now let's take a look at our tree
- git cat-file -p master\^{tree}
- #------------- OUTPUT ---------------------------------------------------------
- # 100644 blob d2617a67f7fd50e85356270658ac6531f7d24bb5 README.md
- # 100644 blob f714a668e17b09bf82809a5b4b3e663d0b250b5c hello.py
- #--------------------------------------------------------------------------------
- # A commit object contains the previous commit sha, the tree sha and some data about the commit itself, the author, an
- # email, date time and a message about the commit.
- COMMIT=$(git rev-parse HEAD) # It's 4738aa0 for me but will be different for you since your email and timestamp differs
- git cat-file -p $COMMIT
- #------------- OUTPUT ---------------------------------------------------------
- # tree 379876d0691c6d83c4e6ff7e89e432abcd159db9
- # parent 671ce2e444ee1c54728a2957dce00dacbe672874
- # author Luke Campbell <luke.s.campbell@gmail.com> 1380031913 -0400
- # committer Luke Campbell <luke.s.campbell@gmail.com> 1380031913 -0400
- #
- # Added hello.py
- #--------------------------------------------------------------------------------
- # Now to push our local changes to our repositories
- git push origin master
- #------------- OUTPUT ---------------------------------------------------------
- # Counting objects: 4, done.
- # Delta compression using up to 8 threads.
- # Compressing objects: 100% (3/3), done.
- # Writing objects: 100% (3/3), 349 bytes, done.
- # Total 3 (delta 0), reused 0 (delta 0)
- # To /tmp/git-example/repo
- # 671ce2e..4738aa0 master -> master
- #--------------------------------------------------------------------------------
- # Our current branch "master" which is a named symbol that points to the commit 4738aa0 has now been "pushed" to the
- # origin repository. So now inside origin, its version of master is identical to user0's.
- # Normally, we would make a pull request here but since user0 believes he owns the upstream as well, he'll go ahead and
- # push directly to upstream without using a pull request.
- git push upstream master
- # Now, it's time for user1 to do some work
- cd ../user1
- # user1 needs to grab the latest changes
- # the first thing user1 needs to do is make a remote, something that tells git where to look
- git remote add origin /tmp/git-example/user1-repo
- git remote add upstream /tmp/git-example/upstream
- # Now, to grab the latest changes
- # This pull command with the --ff-only tells git to download the commit history from upstream for the branch named
- # "master", then to fast-forward the current HEAD pointer to the latest commit in that branch. If it's impossible to
- # traverse the commit tree to reach the latest commit then the trees are disjoint and there is a problem.
- git pull --ff-only upstream master
- #--------------------------------------------------------------------------------
- # remote: Counting objects: 6, done.
- # remote: Compressing objects: 100% (5/5), done.
- # remote: Total 6 (delta 0), reused 0 (delta 0)
- # Unpacking objects: 100% (6/6), done.
- # From /tmp/git-example/upstream
- # * branch master -> FETCH_HEAD
- #--------------------------------------------------------------------------------
- cat << EOF > work
- This is where work goes
- EOF
- git add work
- git commit -m "Adds more work" --author $USER1
- git push origin master
- cd ..
- # Now user1 has to submit a pull request, I can't demonstrate a pull request from the command line but user0 gets an
- # email or a notification that user1 has submitted a pull request, he or she reviews the pull request and determines
- # that the work needs to be merged.
- cd user0
- git checkout master # Ensure that I'm on the master branch
- # The syntax for git-pull is
- # git pull <repo> <branch>
- git pull /tmp/git-example/user1 master
- # If I look at the log, I can see that the changes from user1's work were merged in:
- git log --graph --oneline
- # * a5ae7e9 Adds more work
- # * ee89100 Added hello.py
- # * 92495f8 Initial Commit with README
- cd ..
- # Now, let's see how collaborative and concurrent work looks.
- # user0 is going to work on a file concur0 while user1 is going to work on concur1 concurrently
- cd user0
- # Check out a branch for this feature
- git checkout -b concurrent-work
- cat << EOF > concur0
- Some concurrent work goes here
- EOF
- git add concur0
- git commit -m "User0 concurrent work" --author $USER0
- git push origin concurrent-work
- cd ..
- # user0 now submits a pull-request from his github account concurrent-work:upstream/master
- cd user1
- git checkout -b more-work
- cat << EOF > concur1
- Some other concurrent work goes here
- EOF
- git add concur1
- git commit -m "User1 concurrent work" --author $USER1
- git push origin more-work
- cd ..
- # user1 submits a pull request for review and merging from his github-account more-work:upstream/master
- # user0 will review and merge the pull-requests
- cd user0
- git checkout master
- git pull /tmp/git-example/user1-repo more-work
- git push upstream master
- git pull /tmp/git-example/user0-repo concurrent-work
- git push upstream master
- # Now let's look at the log
- git log --oneline --graph
- #--------------------------------------------------------------------------------
- # * bf7c52e Merge branch 'concurrent-work' of /tmp/git-example/user0-repo
- # |\
- # | * d2176fd User0 concurrent work
- # * | 1f3e488 User1 concurrent work
- # |/
- # * a08c6b8 Adds more work
- # * ad7be0f Added hello.py
- # * a7aadf8 Initial Commit with README
- #--------------------------------------------------------------------------------
- cd ..
- # Now let's work with Rebasing
- cd user1
- git checkout -b rebase-work
- cat << EOF >> work
- More work goes inside here
- EOF
- git add work
- git commit -m "Updates work file" --author $USER1
- # We'll do some more work
- cat << EOF > rebase-file
- Some text
- EOF
- git add rebase-file
- git commit -m "Adds new file rebase-file" --author $USER1
- # Our commit history now looks like
- # * 974ca2d Adds new file rebase-file
- # * 08b26d4 Updates work file
- # * 363fb9e User1 concurrent work
- # * e5f0f90 Adds more work
- # * f21e055 Added hello.py
- # * b525af5 Initial Commit with README
- # If we were to make a pull request as it is, it would end up as a merge commit and it couldn't be cleanly integrated
- # into the master tree. If we rebased this history so that all of our new work was "based on" the upstream/master's tree
- # then it would be an absolutely clean integration without the need of a merge commit and the tree wouldn't branch.
- git fetch upstream # updates the local cache of the upstream-repo's information
- git rebase -p upstream/master
- # Our commit history now looks like
- # * 5dca673 Adds new file rebase-file
- # * 41b9da6 Updates work file
- # * b433b18 Merge branch 'concurrent-work' of /tmp/git-example/user0-repo
- # |\
- # | * 3ae59b9 User0 concurrent work
- # * | 828b36d User1 concurrent work
- # |/
- # * f99f07a Adds more work
- # * a6917fd Added hello.py
- # * 396382f Initial Commit with README
- # Our current work, starting at "Updates work file" is now directly on top of the upstream/master's tree.
- git push origin rebase-work
- cd ..
- # user1 now submits a pull request for this work, user0 receives the pull request and pulls it in
- cd user0
- # Update our current understanding of upstream
- git fetch upstream
- # Checkout the raw tree upstream/master
- git checkout upstream/master
- # Name this commit "pulling"
- git checkout -B pulling
- git pull /tmp/git-example/user1 rebase-work
- # Output:
- # Updating 2934f21..8126db2
- # Fast-forward
- # rebase-file | 1 +
- # work | 1 +
- # 2 files changed, 2 insertions(+), 0 deletions(-)
- # create mode 100644 rebase-file
- # Update the upstream repo with these changes
- git push upstream pulling:master # This pushes our local pulling branch to the master branch on upstream
- # Let's take a look at the new history or tree of the upstream/master tree, it shouuld be clean, it doesn't split, it
- # didn't merge the rebase-work branch from user1 and linear.
- git fetch upstream
- git log --oneline --graph upstream/master
- # * 4cf5c2d Adds new file rebase-file
- # * f91dab8 Updates work file
- # * 6eaf9df Merge branch 'concurrent-work' of /tmp/git-example/user0-repo
- # |\
- # | * 25d1d09 User0 concurrent work
- # * | 08de451 User1 concurrent work
- # |/
- # * afd8b73 Adds more work
- # * 7a57979 Added hello.py
- # * 079e069 Initial Commit with README
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement