Okay Flintb, Let's Talk "Git Command Line"

Things worth noting:

  • ‘git fetch --all’ will fetch everything new from all remotes.

  • ‘git pull’ is the same thing as ‘git fetch’ and ‘git merge’ run in
    sequence. So if you’re on master and you intend to merge remote’s master
    into yours, ‘git pull’ will do the fetch and merge in one shot.


J.

Thank you SO much for all that information. I was able to use that to successfully create a PR for Bug 12980. I mean, it may not be accepted or anything, but at least I created one! :slight_smile:

So my NEXT question for you on this subject goes like this:

  • So now I’ve got my local “vassal” directory filled with the “Bug12980” fix, which meanwhile is in a PR and waiting accept/reject/etc, and could be for a while.
  • But now I’d like to work on a different bug, e.g. Bug13117 or something.
  • It doesn’t touch any of the same files as the other bugfix.

So I imagine what I’d like is a second vassal directory (e.g. instead of …/vassal, perhaps …/vassalbug2), into which I could now pull down the whole kit-and-kaboodle, make & test a set of change for eventually another PR, etc, etc.

So I guess I need to “clone my master” again into that directory, and just treat that as a whole separate block-o-crud? But of course it talks to my github master, that presumably means I need to make a second fork of vassalengine/vassal there?

Now if any of that is wrong or unworkable or a terrible idea, please let me know.

One thing in the your original description that I don’t fully understand yet is the idea of “switching branches” (you refer to switching back to my bugfix branch if I had switched away). So that makes me curious about (a) how would I go about switching away? and (b) WHY would I switch away? Is the idea that I can swap my original “…/vassal” local repository that we created above into other branches, and e.g. use my same directory tree to manage several different sets of fixes/commits? Perhaps that is at least in some cases better than my “multi-fork-multi-directory-tree” plan above? If so then obviously what I’m searching for are the relevant ways to deal with that via useful commands – because presumably when I switch to a branch I need it to pull me down a clean set of files for that branch, etc.

Many thanks,

Brian

Thus spake Cattlesquat:

So I imagine what I’d like is a second vassal directory (e.g. instead
of …/vassal, perhaps …/vassalbug2), into which I could now pull down
the whole kit-and-kaboodle, make & test a set of change for eventually
another PR, etc, etc.

No. What you should do is check out master again, and then make a new
branch off that.

The important thing here is that your local git repo stores all the
branches you have. You can switch between them just by checking out
a different one.

commands – because presumably when I switch to a branch I need it to
pull me down a clean set of files for that branch, etc.

Nope. You already have them. Git stores everything under the .git
directory. When you check out a branch, it recreates the state of that
branch from what it has in .git.


J.

1 Like

Yep switching branches is what you need to do if you want to work on another bugfix, and that is the exact reason why you would want to switch branches.

Speaking in steps:

  1. Done with creating PR for bugfix-1
  2. Switch back to master
git checkout master
  1. Local master possibly got old in the meanwhile, there are new commits in the central master branch, do the “keep master in sync” workflow described above
  2. For bugfix-2, follow the “change code” workflow described above, i.e. create new branch, do commits and so on.

To see which branch is currently selected as the active branch, and whether there are any uncommitted files, do this:

git status

Try to avoid uncommitted files when switching branches, either commit them or revert them.

Thus spake Flint1b:

Try to avoid uncommitted files when switching branches, either commit
them or revert them.

Or stash them, using ‘git stash’.


J.

Ooh, git stash might be a way for me to avoid my project build settings being repeatedly overwritten. (see https://forum.vassalengine.org/t/anyone-know-what-changed-in-vassal-master-since-yesterday/10763/1)

Do you guys presumably make little “batch files” of some of these commands?

p.s. I am SO all about this becoming a wiki entry. Would mean I could also correct the little typos in a few of the commands :slight_smile:

I have created an initial version of the wiki page, it is awaiting moderation now. It’s mostly a copy of my initial guide in this thread with wikimedia formatting, but it’s a start.

Would be good if later on someone whose native language is english could read it and correct my mistakes, I might have learned proper Oxford English when I was young but decades on the internet with it’s various englishes and people writing “could of” and “there there there” instead of “their there they’re” have spoiled me.

Cool I’ll keep an eye out for it and give a pass through. I think your english is fine (you “could have passed” to me!). By edits I was referring to a couple syntax errors like ’ instead of " around a string, and a missing “commit” keyword, that kind of stuff.

Now a question from me, I’m not such a git master after all:

In a situation where a master has one remote master, yes, git pull.

But what if my local master branch has a ‘remote’ and an ‘upstream’, the ‘remote’ is in sync but the ‘upstream’ has new commits? Will ‘git pull’ fetch from both, see that ‘upstream’ has the more recent commits, then merge from ‘upstream’?

Thus spake Flint1b:

“uckelman” wrote:

  • ‘git pull’ is the same thing as ‘git fetch’ and ‘git merge’ run in
    sequence. So if you’re on master and you intend to merge remote’s
    master
    into yours, ‘git pull’ will do the fetch and merge in one shot.

Now a question from me, I’m not such a git master after all:

In a situation where a master has one remote master, yes, git pull.

But what if my local master branch has a ‘remote’ and an ‘upstream’, the
‘remote’ is in sync but the ‘upstream’ has new commits? Will ‘git pull’
fetch from both, see that ‘upstream’ has the more recent commits, then
merge from ‘upstream’?

When you first push a branch, you may have seen a message reminding you
to set an upstream for the branch (because you forgot to specify the
-u or --set-upstream argument). The argumnent -u wants is the name of
a remote. When you push with ‘-u somewhere’, this will cause there to
be a line which looks like ‘remote = somewhere’ to be written to your
.git/config in the section corresponding to your branch. Thereafter, if
you do a ‘git push’ (or ‘git pull’) on that branch without specifying
a remote, the one you set with -u is used as the default.

That is, ‘git pull’ will pull from the remote you set with -u. If you
want to pull from any other remote, you need to tell ‘git pull’ which
one, so e.g. ‘git pull somewhere_else master’.


J.

So, say I got my push all done and discovered it accidentally caught an extra file I didn’t want (in my case, usually “.classpath”).

Github was offering me a “delete” button and I thought that was going to purge that file out of my PR, but no apparently it was trying to delete it from the repo.

So in that case, is there a way in git to… reach into my existing PR and say “please remove from this PR all the changes to this one particular file”?

Tried to google some git stuff and I seemed to get as far as at least getting rid of the “delete” command from one of my PR’s, but it still wants to be touching the file.

I’m getting better at keeping .classpath from getting picked up in my commit in the first place, but I might as well learn how to knock unwanted things back out. If anybody knows how.

Brian

I had a similar problem where a commit I didn’t want got sucked into a PR. I just had to un-make the change and commit again. This adds an extra commit to your PR, but the PR process works by diff between the current master and the sum of your PR commits, so the unwanted commit ‘disappears’ from the PR.

There is now a wiki page for this: vassalengine.org/wiki/Using_Git

A link to that page from the wiki’s main page / development section is awaiting moderation.

Looks great – I just saved (to moderation of course) a few minor changes. There was one of the early examples where the keyword “commit” was actually missing from a couple of the git command lines. And I made a few minor “englishy” tweaks.

One thought I have – at one point you offer this command line:
git commit -a -m ‘applied requested changes’

And I think the “-a” is the part that was slurping up my .classpath into some of my early commits? I eventually learned to just do “git add” where needed and commit with a regular “git commit -m” and no -a and that seemed safer, since I that way I am always explicitly naming the things I want staged for commit and nothing gets put in there “automatically”.

So possibly you might want to teach that workflow instead? Anyway just an idea.

The git introduction is absolutely wonderful for someone like me!

Brian

Uh oh - so did I, I guess someone will have fun merging them :unamused:

Haha!

So meanwhile “Today in WTF Have I Done” – could you please take a peek at the weird relationship between PR34 and PR35?

What “I thought happened” yesterday was:
(1) I made an HTMLChatter branch and did a bunch of chatter-y stuff. Pushed. Made a PR.
(2) You reviewed the code, I made the changes in two batches. Pushed them. They showed up in PR. Yay, all is well.
(3) Meanwhile I got started on fixing the drag-the-whole-contents-of-deck problem, creating a Bugfix13036 (or whatever number it is) branch. Made the fixes. Pushed. Made a PR.
(4) But today when I went to LOOK at the Bugfix13036 PR (35), it seems to have all the Chatter commits in that PR too?!?!
(5) So then I thought “uh oh I committed them to the wrong place that means they’re not in the Chatter PR”… but I’d remembered them showing up when I was making the changes, and sure enough when I went back to PR 34 “there they are”.

So I’m not really sure what happened or even what on earth is going on, I’m afraid. I thought I was changing two completely different files in two completely different branches, but Git seems to (maybe?) think things are somehow conflated together.

Anything I can do to repair? Or am I misunderstanding something and everything is actually okay?

Brian

I cloned your github repo and here is what I see:

  • your origin/master (head i.e. latest commit in your master branch) is at commit b6ed17
  • your branch origin/HTMLChatter branches off of commit b6ed17 and adds 3 commits on top of that (f88ba4, d53096, 4b5327)
  • then your branch origin/Bugfix13036 branches off of commit 4b5327 of the HTMLChatter branch (!) and adds commit e04a12 on top of that

A PR is the difference between the master and the PR’s branches head.

The difference between master and your branches (the path from master to the branch head) is:

  • from master to HTMLChatter: commits f88ba4, d53096, 4b5327
  • from master to Bugfix12036: commits f88ba4, d53096, 4b5327, e04a12

This is because you branched Bugfix12036 off of HTMLChatter, if you had branched Bugfix12036 off of master it would look like this:

  • from master to HTMLChatter: commits f88ba4, d53096, 4b5327
  • from master to Bugfix12036: commit e04a12

Now this may be a mistake or may be correct, if the changes of Bugfix12036 have nothing to do with HTMLChatter then it’s probably a mistake, but sometimes the changes of one bugfix depend on the changes of another.

Now there’s two options, you either leave it as it is if the changes of Bugfix12036 depend on HTMLChatter, or you correct this.

If you leave it as it is, you can leave a comment under the Bugfix12036 PR and say that it should be merged AFTER HTMLChatter got merged, then the following will happen:

  • HTMLChatter will be merged, git will add commits f88ba4, d53096, 4b5327 to master
  • then the difference between master and Bugfix12036 will be commit e04a12 (since the other 3 commits already are in master)
  • the Bugfix12036 PR will change to only contain that one commit

If you want to fix it, you use my favorite part of git, the “rewrite history” part:

  • close the PR (or will it close automatically when we do the next step… it probably will?)
  • delete the Bugfix12036 branch on github (not the local one): git push origin --delete Bugfix12036
  • locally, run the following: git rebase --onto master HTMLChatter Bugfix12036
    This basically says, “Take the Bugfix12036 branch, figure out the patches since it diverged from the HTMLChatter branch, and replay these patches in the Bugfix12036 branch as if it was based directly off the master branch instead.”
  • then proceed as usual, push the Bugfix12036 branch to github and create a new PR

I admit I don’t know all of git by heart, I had to look up here git-scm.com/book/en/v2/Git-Branching-Rebasing :smiley:

Beautiful! Worked perfectly, thanks! (Yes I rebased it, they were completely unrelated and independent fixes).

My small followup is… making sure I understand how I managed to do that in the first place. Does this mean I was switched to HTMLChatter branch at the time I did my “git checkout -b Bugfix13036”? And the way to prevent that in the future (when I don’t WANT to create a dependent fix branch, of course) is to make sure I do the “git checkout master” drill to switch back, before the next “git checkout -b …”?

Thanks SO much! At least by the time Joel sees them they will be nice clean PR’s :slight_smile: Hopefully there will be enough value to the project to justify the time spent getting me git-literate…

Brian

Yes exactly, the “checkout -b branchname” always branches off the currently selected branch, so first switch to master, then make a new branch.

And I just realized that I’m teaching the father of Civ2 how to use git, I bow down before you sir, you are part of the reason why I discovered wargames so late, the computer strategy games were just too good :slight_smile:

Haha glad you liked it! I wrote all the game code, AI, and most of the interface code for that … back when you traded code by copying everything into some directory on the LAN. I think we had our first source control (Sourcesafe) for the next game, Alpha Centauri, and then it was Perforce for most of the rest of my active time doing coding. I actually found, when I recovered my account on here, that I’d actually checked in honest-to-goodness code for Dominations on April 2, 2013, when I was briefly using git, but I’d clearly forgotten everything :slight_smile: Good times.