CS 458 - Week 3 Labs - 11 am lab - 2017-09-96

*   REMINDER: recommended philosophy for commits:
    *   do SMALL commits OFTEN <-- shades of XP's
                                   continuous/frequent integration
    *   BUT!
        try to only commit things that COMPILE and WORK
	(leave the repo in a "good" state)

	^ hopefully a commit could be committing the WORKING
	  work for some user story, for example;

    *   use "social mechanisms" to get people/team members
        to go along (for example, team agrees that only
	code that passes its unit tests will be committed
	to the team repo,
	since we don't have an automated tool to enforce 
	this)

*   REMINDER: commit three-stage thinking
    *   say you are part of a pair working on a user story
    *   work on a file that is part of that;
        when the pair decides it is in a good stage,
	STAGE that file
        *   (the staged files at any point, then,
	    are those you consider in good shape
	    for the next commit)
    *   when all the files for that user story
        are in good shape and staged,
	THEN commit <-- this is a small milestone in the
	                project's history that you might
			want to be able to come back to
			or roll back to

*   here's ONE version of a team-based workflow:
    *   (from a past CS 480 - Extreme Programming)
    1.  get the newest changes from the main repo:

        git pull
	 
	^ with no additional arguments, this should pull
	  from the repo your clone originated from,
          I *believe* from its master branch

    2.  make changes to a file you wish to change

        e.g.,   nano ideas.txt

    3.  remember you can check out your repo's
        status at any time with

	git status

    4.  when I think that file is ready to be staged,

        git add ideas.txt

    5.  (do what work is desired in other files,
        stage them as they are ready,
	when current local repo is in a "good" state,
        with the proper files staged,
	)
	...commit the local repo

	git commit -m "have finalized today's ideas"

    6.  step 5 JUST committed your local repo!

        to PUSH the changes to the originating repository:

	git push origin master

                 ^ origin is set to the location you
		   cloned this local repo from

                        ^ which branch of the local repo are
			  you pushing

*   branching!

*   you SHOULD create branches to try out new
    things; "alternate universes", if you will;

    pitch 'em if you decide you don't want them anymore,
    merge 'em if you want to ADD them into another branch;

    *  steps:

       *   create a branch

           git branch <desired_new_branch>

       *   then, to work in a branch, you check it out

           git checkout <desired_branch>

       *   you can see the names of all current branches:

           git branch

       *   you can see the latest commit on each branch
           with:   

	   git branch -v

       *   do the work you are going to do
           ...stage that work, commit that work,
	   decide you LIIIIKE this branch.

	   You WANT to merge it into your master branch
	   (or just another branch)

	   *   FIRST go back to/check out the branch
	       you want to merge INTO,
	       THEN merge the "new" branch INTO that
	       branch

	       to merge my_new_branch into the master branch,

	       git checkout master   # go to branch to merge INTO
               git merge my_new_branch # merge my_new_branch INTO
	                               #    master branch

    *   git branch -d <branch_name>
        ...DELETES the branch <branch_name> from your project

*   merge CONFLICTS
    *   what if, upon attempting a merge of a branch,
        one or more files in both branches are BOTH
	changed in DIFFERENT ways?

        ...you'll get one or more files with MERGE CONFLICTS

    *   in the current branch,
        the files with merge conflicts have additional
	lines added,
	called conflict resolution markers

	<<<<<<< HEAD
        blah blah
        =======
        bleah bleah
        moo
        >>>>>>> other_branch

        *   you EDIT each conflicted file,
	    and REMOVE the conflict resolution markers

	<<<<<<< HEAD
        =======
        >>>>>>> other_branch

            ..when you are done.

    *   you indicate you have resolved the conflict
        by staging the files with conflicts
	and then committing:

	git add <problem-file>
	...
	git commit -m "took care of flavor misunderstanding"

*   some more terminology...
    *   a remote is a shared Git repo thst allows multiple
        collaborators to work on the SAME git project from
	DIFFERENT locations

        ^ your team's upcoming private GitHub team repo
	  will serve as your team project's remote

        *   (paired) collaborators work on their cloned version
	    of the remote separately, and merge changes
	    to the remote as appropriate

        *   git clone <remote_location> <clone_name>
                      ^ can be a web address OR a file path

                                        ^ if omitted, clone's
					  name will be the same
					  as the cloned repo's name
    *   when you clone a repo via <remote_location>,
        the name/alias

	origin

	is given that remote location, for convenience

    *   git remote -v

        ...you can see the value of your cloned repo's
	   fetch and push remotes;

*   git fetch

    ...lets you see if changes have been made to the
    origin since you cloned from it;

    IF there were changes, this BRINGS those changes
    onto what is called a "remote branch"

    you can, if desired, MERGE those changes with your local
    master branch with a merge:

    git merge origin/master

*   waitaminnit --
    what is the difference between
    	 git pull
    and
         git fetch
	 git merge origin/master

    *   according to a stackoverflow posting...
        *   basically, git pull
	    DOES a git fetch followed by a git merge;

        *   it does look like the earlier workflow's
	    suggestion of STARTING your latest
	    pair's work on a local copy with
	    a 

	    git pull

	    from the shared remote is indeed a good
	    idea, as you WANT to start with any
	    changes in place;

*   here's ANOTHER suggested workflow, now making better
    use of branches (adapted
    from Codecademy's Git collaborations course, I think):
    1. do a git pull to start with the team's latest committed
       version

    2. create a branch to work on the next user story
       your pair is working on locally

    3. check out that branch, develop the feature,
       staging the files as you get them ready
       and committing when you think the feature is
       complete;

    4. fetch and merge from the remote
       (I think into this branch!)
       to get any committed changes since step 1

    5. push your resulting branch to the remote for
       review

       git push origin your_branch_name

    ...now someone on the team can review the pushed branch
    now pushed to the remote, 
    and if it looks good/safe/etc., merge the branch
    into the remote's master;

*   PART 1 - a FEW words on backtracking
    (with more to come)

    *   FIRST: the commit you are currently on is known
        as the HEAD commit (in many cases, this is the
	most-recently-made commit)

	git show HEAD

        ...will let you see the HEAD commit

   *   git checkout HEAD <filename>

       will RESTORE <filename> in your working directory
       to look exactly as it did when you made the HEAD commit
       (probably the latest commit)

   *   git reset HEAD <filename>

       lets you UNSTAGE <filename> from the staging area;
       (does NOT change <filename> in the working directory)

*   MORE on changes/rolling back/other possibly-dangerous
    git actions later...