CS 458 - Week 3 Labs - 9 am lab - 2017-09-06

*   REMINDER: a recommended philosophy for commits

    *   do small commits often <-- shades of XP's
        frequent/continuous integration

    BUT ALSO
    *   try to ONLY commit things that COMPILE and 
        WORK (leave the repo in a "good" state)

        ^ social engineering version, perhaps,
	  of only committing code whose unit tests
	  pass -- members say they won't commit code,
	  let's say, whose unit tests don't pass

    *   use social mechanisms to get team to go along
        (if you don't have an environment that
	enforces only-add-code-whose-unit-tests-pass,
	for example)

*   REMINDER: commit three-stage thinking

    *   work on a file
    *   STAGE the file for the next commit
    *   [when all the files for the latest task
        are good, project compiles, unit tests
	pass, etc.]
	then COMMIT the staged files
	
*  here's one slightly-expanded set of steps
   as recommended by the CS 480 - Extreme Programming
   class a number of years back...
   1.  get the NEWEST UPDATES from the main repo
       (note that this DOES change your local copy,
       so do it BEFORE you make changes to local files)

       git pull   # version for pulling from repo you 
                  #    cloned from

   2.  nano test.txt # make file changes as desired

   3.  at any time,
       git status    # to check repo status

   4.  when a file is done/ready, stage it for the
       next commit:

       git add test.txt

   5.  when all the files are ready (and will leave
       the repo in a good, working state)
       then you can try committing them (this only
       affects your LOCAL COPY of the repo)

       git commit -m "descriptive msg for task"

   6.  push the changes back to the main repository

       git push origin master
                ^ where you are pushing TO (here, where
		  I cloned it from)

                       ^ is which branch is being pushed


BRANCHING
*   it is GOOD to create alternate universes -- branches
    -- to try things out!

*   basic steps
    *   create a branch

        git branch <desired_new_branch_name>

    *   check out/go to that branch

        git checkout <desired_branch_to_work_on>

    *   want to see your current branches?

        git branch

        ^ also indicates WHICH you are in right now!!

    *   git commit -v

        ^ will also show the last commit on each branch
          (might need pretty-fying...!)

    *   git branch -d <branch-to-delete>

        deletes <branch-to-delete> from your Git project

    *   git merge <new-branch-to-merge>

        this attempts to merge <new-branch-to-merge>
	into the CURRENT branch

        *   that is, something like this:

	    git branch new-one
            get checkout new-one
            ... work work work ...
 
            ...hey, I like it! ...

            git checkout master # GO to branch to merge INTO
            git merge new-one   # merge new-one into current

*   what if there is a merge conflict?
    *    the files with conflicts (in the current branch)
         will have additional lines added,
	 called conflict resolution markers

         maybe something like this:

	 <<<<<<< current-branch
         =======
         >>>>>>> branch-to-merge
       
         you carefully make the changes to get the
	 desired version of conflicting files,

	 carefully remove the conflict resolution
	 markers,

	 and STAGE those changes to mark the conflict
	 as resolved

	 and then commit the results;
    
*   a remote is a shared Git repo that allows multiple
    collaborators to work on the same project;

    (in CS 458, you will be using your team's private GitHub
    repo as a remote, then)

    we've already discussed A version of this:
    git clone <remote_location> <clone_name>

                                ^ if omitted, clone's name is
				  the same as the remote repo's
				  name

    *   when you clone a repo via <remote_location> as
        above, Git gives this remote location
	the nickname/alias:

	origin

        (so,	
	    git push origin master

	    ...is pushing the master branch to the origin,
	       the location of the original repo cloned from)

    *   git remote -v

        ...shows you a list of the (current?) Git project's
	remotes (for fetch AND for push...!)

    *   git fetch

        sees if changes have been made on the origin repo
	and BRINGS them (but does not merge them) to
	your local repo

	git merge origin/master

	...says to MERGE the changes from the origin's
	master branch into the local repo

*   what is the difference between the above
    and git pull?

    *   basically, git pull does a git fetch
        and then a git merge

    *   git pull
        does seem appropriate, then, when you
	are updating your "clean" local repo
	to the team's latest version before doing
	work;

*   ANOTHER suggested workflow:
    1.  start with either
        git pull

	or 

	git fetch
	git merge ...

    2. create a new branch to work on a next project user story

    3. develop the user story on your branch,
       and commit your work

    4. git pull OR fetch-and-merge from the remote again
       (in case new commits were made in the meantime)

    5. PUSH your branch up to the remote for review

       git push origin <your-branch-name>

       ...will push your branch <your-branch-name>
       up to the remote, origin

       ...and someone can review that pushed branch
       <your-branch-name> and if acceptable,
       carefully merge it into the origin's/remote's
       master branch,
       making it part of the DEFINITIVE project version

*   a few words on BACKTRACKING...

    *   the commit you are currently on is known as the HEAD
        commit

    *   git show HEAD
        ... lets you see which commit is the HEAD commit

    *   git checkout HEAD <filename>

        ...will restore <filename> in your working repo 
        to look exactly as it did when you LAST made a commit

    *   what if you have staged/added a file 
        and you want to UNSTAGE it:

	...use git reset:

        git reset HEAD <filename-to-unstage>

        *   it does not discard file changes from the working
	    directory, it just removes them from the "staging
	    area"

*   careful rewinding -- 
    ...we'll talk about this later;