[HN Gopher] Git In Two Minutes (updated after 8 years)
       ___________________________________________________________________
        
       Git In Two Minutes (updated after 8 years)
        
       Author : garyrob
       Score  : 193 points
       Date   : 2022-08-06 18:03 UTC (4 hours ago)
        
 (HTM) web link (www.garyrobinson.net)
 (TXT) w3m dump (www.garyrobinson.net)
        
       | ArrayBoundCheck wrote:
       | I wish they made a breaking change in the next version and make
       | the CLI actually usable.
       | 
       | Before you downvote, ask yourself how do you list tags, branches
       | and remote
        
         | mmcclimon wrote:
         | While acknowledging that git's CLI is often unintuitive: `git
         | tag` lists tags, `git branch` lists branches, and `git remote`
         | lists remotes, so I don't think I understand this particular
         | objection.
        
           | ArrayBoundCheck wrote:
           | Compare it with `git branch -a` and `git remote -v`. That's
           | my point. Not only are they all different flags but you'll
           | get half the data you could be getting and not know why. It's
           | impossible to google
        
         | umanwizard wrote:
         | They shouldn't break the existing `git` command as it is widely
         | used in scripts. But there are projects that try to build
         | better UIs on top of git; the most serious such attempt that I
         | know of is magit.
        
         | ajross wrote:
         | "git tag", "git branch -a", "git remote -v"
         | 
         | You point is what, that these are needlessly asymmetric? It's
         | true. But they're in my head because I do them every day, and
         | it's not like I'm suffering under the burden of remembering a
         | handful of flags. That's a pretty far cry from "not actually
         | usable", so maybe your hyperbole is a little misplaced?
        
           | ArrayBoundCheck wrote:
           | Correct. That was a simple example that's easy to understand
           | 
           | Anyone with half a brain can understand that if they can't
           | keep something as simple as printing a list consistent you
           | better believe nothing else will be straightforward. Which is
           | my point. NOTHING is straightforward and I haven't met a
           | single person who likes the CLI if they do anything more
           | complex than a commit, push and pull. I know people who still
           | refuse to use rebase and don't understand bisect or blame.
           | They use a GUI to restore files
        
         | PeterWhittaker wrote:
         | Branches are easy, what with them being only labels:
         | 
         | > git branch --all
         | 
         | Tags are different, since they are actual objects in git, but
         | using ls-remote isn't tough, and one could create an alias.
        
       | probably_wrong wrote:
       | > _it it's enough be useful for beginning solo developers, and
       | provides a start from which you can grow._
       | 
       | I like this guide a lot as a cheatsheet. However, when it comes
       | to beginners I fear it is one of those things that make sense
       | only when you already know what the guide is talking about.
       | 
       | It would take me more than two minutes just to explain a
       | completely new developer what a commit is and why they would want
       | one. And God help us if I throw the output of "diff" at them
       | without warning...
       | 
       | The sad truth is, you cannot explain git in two minutes. I
       | nonetheless admire the author for giving the problem a fair
       | fight.
        
       | spaceman_2020 wrote:
       | as a noob trying to pick up coding just to experiment with some
       | ideas, I always found Git to be surprisingly confusing. I feel
       | that a lot of the command names aren't very intuitive.
       | 
       | Or am I just an idiot?
        
         | garyrob wrote:
         | I agree with you. What I do is use the snippets from the blog
         | post without particularly thinking about them!
        
         | sedatk wrote:
         | Git is confusing. Alternatives like Mercurial are way more
         | intuitive and easier to use, but they lack popularity.
        
         | umanwizard wrote:
         | I don't know whether you're an idiot or not, but thinking git
         | is confusing is certainly not evidence to that effect.
         | 
         | Git _is_ confusing; it became the de-facto standard because it
         | was the first free DVCS (and DVCSs solve lots of problems that
         | were common to old non-distributed VCSs), not because its UI is
         | particularly well-designed.
        
         | kadoban wrote:
         | Git's command names, and UX in generaly, is its worst area.
         | It's definitely not just you.
         | 
         | Many professional software devs I work with still really have
         | no idea how git works, they've just memorized the 3 or so
         | commands they absolutely need and maybe how to recover when
         | something out of the ordinary happens.
        
         | probably_wrong wrote:
         | When it comes to git, I am firmly of the opinion that it's not
         | you, it's them.
         | 
         | Git is simple, but it takes a lot of experience to appreciate
         | its simplicity. So don't beat yourself up, git is _hard_ and it
         | 's okay to be lost.
        
         | sureglymop wrote:
         | I think what makes it more confusing is that the inner workings
         | are almost too simple.. so one wonders why there are so many
         | commands etc.
         | 
         | Git is basically a linked list (if you have one branch) and a
         | graph (if you have more than one branch). Then all you are
         | really working with are _pointers_ to certain nodes in that
         | graph.
         | 
         | In git terminology these nodes are called objects and there are
         | different types of objects such as tree objects and commit
         | objects etc. Objects are compressed with a library called zlib
         | and are stored as files within the .git/objects directory, the
         | file name is the hash of the decompressed object.
         | 
         | But, back to the graph and the pointers to certain nodes. A
         | branch itself is nothing more than a pointer either. You can
         | look at the files in .git/refs/heads to see where they point.
         | 
         | Now, what you do with git checkout is changing the node you
         | currently view in the graph. If you make a commit you create a
         | new node. Merging is nothing more than taking two nodes and
         | creating a new node that is connected to both of them.
         | 
         | The main problem i think is that concepts like branch, tag,
         | commit etc are actually just overcomplicated abstractions of
         | the much simpler graph nodes and pointers and are thus
         | confusing.
        
         | jonnytran wrote:
         | Git isn't designed for "noobs trying to pick up coding just to
         | experiment". It also isn't really designed for solo developers
         | as the OP is about.
         | 
         | Git is designed for collaboration. Git's UI is absolutely
         | unintuitive, especially coming from other version control
         | software. But that's irrelevant. Everyone wants to use it
         | because of the network effect.
         | 
         | In terms of _why_ the UI is unintuitive, I believe it's because
         | it intentionally exposes its internal representation. Unlike
         | its predecessors like subversion, Git has infinite flexibility
         | in terms of the workflow that teams of people can adopt. But
         | the flexibility comes at the cost of learning how to use a
         | distributed graph of commits.
         | 
         | Personally, I never learned git by reading recipes of commands,
         | like the OP. I only really grokked it by understanding how it
         | works internally. This article helped me:
         | 
         | Git for Computer Scientists https://eagain.net/articles/git-
         | for-computer-scientists/
        
           | COMMENT___ wrote:
           | > Git has infinite flexibility in terms of the workflow that
           | teams of people can adopt.
           | 
           | IMO flexibility is just a meaningless buzzword used to
           | describe overly complicated and poorly designed products. If
           | a product has crappy UX, they just call it "developer
           | oriented" and "flexible".
           | 
           | When I read about "flexibility" of a software product, I
           | think that this product is of low quality. And that I will
           | have to spend some time to make it work for me (hours? days?
           | weeks? years?). To me as a user this flexibility does not
           | matter at all.
           | 
           | The product either works or it doesn't. If it works, I don't
           | want to spend a career to learn its internals. I just want it
           | to support my use case and give clear step by step
           | instructions in its documentation.
           | 
           | I better spend my time on something more important than
           | exploring how this or another crappy software product is
           | flexible.
        
         | jimbobimbo wrote:
         | I have 20+ years of professional experience and I'm using git
         | via Visual Studio or VSCode UI. I'm not feeling ashamed of
         | that.
        
       | ducktective wrote:
       | obligatory `lazygit` plugging. I do this because this project is
       | criminally underrated: https://github.com/jesseduffield/lazygit
        
       | garyrob wrote:
       | About 8 years ago, I blogged a very brief guide to using git for
       | a solo developer. A lot of people seemed to like it.
       | 
       | A couple times since then, I've noticed there was something I was
       | using that wasn't in it, but that could be added without making
       | it significantly longer or more complicated. So there were a
       | couple of updates.
       | 
       | I did another one today, and had the thought that since this
       | guide now includes the benefit of 8 years of practical experience
       | in actually using it, while still essentially being "Git In Two
       | Minutes", it might be worth posting to HN. So here it is.
       | 
       | It doesn't say anything about github. It really is for a solo
       | developer who wants to start using git in a very painless way.
       | With the additional goal that you can profitably use git for
       | years without going beyond the described features.
       | 
       | https://www.garyrobinson.net/2014/10/git-in-two-minutes-for-...
        
         | noja wrote:
         | Without switch and restore, it is not modern git!
        
         | boredemployee wrote:
         | thank you very much. I'm always reluctant to read/watch _any_
         | git tutorial, I think that will help me a lot!
        
           | garyrob wrote:
           | I hope it does!
        
         | notRobot wrote:
         | Thank you for this!
        
         | moritonal wrote:
         | Hey, just a heads up (won't be a problem for most people
         | Goolging git) but on mobile (Firefox) the code blocks are
         | almost unreadable because they're so small.
        
       | boustrophedon wrote:
       | In both examples given in the "Undoing a bad commit" section
       | (fixing a commit message and fixing an error in a file) it's
       | easier to make the change and then run `git commit -a --amend`
       | which takes the current changes you have and adds them to the
       | last commit, allowing you to change the commit message as well.
       | 
       | There are other cases where git reset is useful, but generally
       | not for the reasons given.
        
       | carom wrote:
       | How does this not mention git push? That and pull seem a lot more
       | essential than everything that came after commit.
        
       | nmz wrote:
       | Absolute crap article.
       | 
       | You don't learn git in two minutes if you don't talk about rebase
       | and remotes.
       | 
       | You want to learn a dvcs in 2 minutes? try fossil.
        
       | demarq wrote:
       | Guides like these are an absolute treasure when on-boarding
       | junior devs.
       | 
       | It can be really difficult distilling all you know about a
       | certain topic into something short and concise like this.
        
         | malkia wrote:
         | Hey not only junior developers - there are senior ones (like
         | me) that need it too! So thanks for all these "one-pagers" that
         | are easy to remember.
        
           | demarq wrote:
           | haha but of course!
        
       | candiddevmike wrote:
       | Why do they have '--' as an argument in a lot of the commands? I
       | don't think that's necessary?
        
         | PeterWhittaker wrote:
         | To quote TFM:
         | 
         | > This option can be used to separate command-line options from
         | the list of files, (useful when filenames might be mistaken for
         | command-line options).
         | 
         | This is a common idiom, e.g., to grep a file for a pattern that
         | matches a grep argument,
         | 
         | > grep -- -e file
         | 
         | Edit: fixed dash weirdness.
        
         | gizmo686 wrote:
         | It forces git to intereperet what comes after as paths.
         | Normally this is not needed, but occasionally you get a
         | filename that causes ambiguity.
         | 
         | For instance, "git checkout test.c" will check out the file
         | test.c unless you happen to have a branch called "test.c". (See
         | also people complaining that checkout is overloaded".
         | 
         | Simmilarly, "git add --verbose test.c" will add test.c, and log
         | that to stdout. "git add -- --verbose test.c" will add test.c
         | and --verbose, where "--verbose" is the name of a file.
         | 
         | This isn't git specific, most CLI tools use "--" to restrict
         | the parsing on arguements that follow.
        
       | soupshield wrote:
       | What do we call the "--" part in a command like this:
       | git checkout HEAD -- <filename>
       | 
       | I find it hard to remember things unless I understand their
       | purpose. It looks like it's specifying an argument but without an
       | argument name (e.g. --verbose), unless it's similar to a pipe |
       | symbol and <filename> is being passed to the checkout command as
       | some special kind of argument?
        
         | swordbeta wrote:
         | https://unix.stackexchange.com/a/11382
        
         | ttymck wrote:
         | It is a delimiter indicating the end of options:
         | 
         | https://unix.stackexchange.com/questions/11376/what-does-dou...
        
         | gizmo686 wrote:
         | I don't know what it is called, but it forces what comes after
         | to be interpreted as a filepath.
         | 
         | This is not git specific, but a common convention for CLI
         | tools. Try running:                   > touch -- -i foo
         | > rm -- -i foo
         | 
         | And compare what happens without the "--".
        
           | soupshield wrote:
           | Thank you for this brilliant explanation (complete with
           | interactive example :) I completely get it now.
        
           | pojzon wrote:
           | Not only a filepath, this means pass anything past "---" 'as
           | is' as an input and not an option flag.
           | 
           | docker run -it nginx --- ls la
        
             | soupshield wrote:
             | Ah yes I've seen it in those kind of contexts too. Thanks
             | everyone this has really clicked in to place for me :)
        
             | drdec wrote:
             | Not a file path specifically and not an input exactly but I
             | think the proper word would be an argument.
        
           | tremon wrote:
           | And then we have startx, which starts both an X server and
           | the X client specified:                 startx
           | /path/to/client --with --client-options and arguments --
           | --server-options -go --here
           | 
           | Here, the double dash is used to separate the client options
           | from the server options (the path to the server binary is
           | compiled-in, IIRC).
        
         | wruza wrote:
         | It means "stop processing arguments as options and leave them
         | alone" to getopt-likes. E.g. to rm file named "-f":
         | rm -- -f
         | 
         | Idk the word, just minus minus.
        
           | soupshield wrote:
           | > E.g. to rm file named "-f":
           | 
           | I've defintely had this sort of problem in the past :)
        
             | vultour wrote:
             | rm ./-f
        
       | kelthuzad wrote:
       | I found the "Missing Semester" lectures on YouTube to be pretty
       | helpful:
       | 
       | Regarding git there is:
       | 
       | Lecture 6: Version Control [0]
       | 
       | [0] https://youtu.be/2sjqTHE0zok
        
       | anderskaseorg wrote:
       | These days it might be better to teach new users about 'git
       | switch' and 'git restore' (added in Git 2.23, released
       | 2019-08-16) rather than the two overloaded meanings of the
       | confusing 'git checkout' command.
       | 
       | https://git-scm.com/docs/git-switch
       | 
       | https://git-scm.com/docs/git-restore
        
         | ajross wrote:
         | My feeling is that new users shouldn't be taught about branches
         | in their local repo at all. Typical cloud-based
         | git{hub,lab}/gerrit/etc.. workflows generally store all
         | branches worth talking about on remote systems anyway.
         | 
         | I find I don't ever bother with managing local branches for
         | anything in my own workflows. I just git-reset --hard to bounce
         | between fetched copies of upstream branches as needed. Stuff I
         | need to work on for more than a few commits in an afternoon
         | gets pushed to a remote branch regularly anyway as part of
         | general safe development hygiene.
        
         | chasil wrote:
         | My developers use CVS.
         | 
         | Sometimes, they are really stupid, and they will checkin
         | passwords.
         | 
         | With the RCS archives, I can use vi (or nano, or any other
         | reasonable editor), and remove this foolishness.
         | 
         | When I run "git cvsconvert" any foolishness is _ENGRAVED IN
         | STONE_.
         | 
         | Removal is possible in git, but not easy.
         | 
         | This is my problem. THERE ARE SO MANY IDIOTS. What can I do?
         | 
         | EDIT: For Windows-centric users of git, you need to run this in
         | every and all repositories RIGHT NOW.
         | 
         | git grep -i password $(git rev-list --all)
         | 
         | [actually, everybody should try it]
        
           | AnonCoward42 wrote:
           | I might be an idiot myself, but would `git rebase -i
           | <commitBeforeSnafu>` do the trick?
           | 
           | edit: This is interactive rebase, where you can rewrite
           | history. Instructions are in the file you are editing once
           | the command is executed. As a rule of thumb, don't rebase on
           | production, however with such a SNAFU you probably need to.
        
             | gizmo686 wrote:
             | No. The old commits still exist, a rebase just makes it so
             | that they are not part of the history of the current
             | branch. If you know the commit hash of a commit containing
             | the offending data, you can still check it out. You can
             | also find such commits in the reflog, or if they are part
             | of the history of any other branch or tag. The data is also
             | in git's internal data structures if you know enough to
             | interpret those directly.
             | 
             | Still, a rebase is a critical part of fixing this. If you
             | rebase every branch that has the offending data in their
             | history, and recreate any tags that have the data, then the
             | offending data would be present only in unreachable objects
             | (which can still be found through the reflog or knowing a
             | commit hash). Eventually, git's garbage collection will
             | clean up such unreachable data. You can force this
             | behaviour earlier by using the `git gc` command. By default
             | git will not remove recent objects (which is why you can
             | reflog your way out of a botched rebase), but you can
             | override this behaviour as well.
             | 
             | Of course, all of the above assumes you are working on your
             | own repository. Given git's decentralized design, you need
             | to clean up and garbage collect on every clone that did a
             | fetch since the offending data was checked it. Worse, each
             | clone also keeps track of remote branches, and considers
             | those to be reachable as well, so a garbage collection will
             | not work correctly until a given clone fetches from all of
             | its remotes after those remotes removed the offending data
             | [0].
             | 
             | Further, there is not good tooling to check that you
             | actually did this correctly, so when you are done, you need
             | to hope you fully purged the data.
             | 
             | The plus side of all of this is that once something is
             | checked in, it is extremely difficult to accidently delete
             | it. The downside is that it is also difficult to
             | deliberately delete it. Also, it is fairly easy to make it
             | difficult enough to find to negate the day to day benifets
             | of it still existing, which does very little to protect
             | against a motivated attacker.
             | 
             | [0] Fourtuantly, you do not need all of the remote to have
             | garbage collected, so you could have every make the data
             | unreachable, fetch on all remotes, then garbage collect.
        
           | ramadis wrote:
           | Chill?
        
             | chasil wrote:
             | What is really far more critical to understand is that my
             | vi changes what everybody sees in CVS.
             | 
             | If there is some foolishness, git propagates it EVERYWHERE.
             | 
             | Every git repository is equal. I have no control of
             | proliferation.
             | 
             | Sigh.
        
               | alvarlagerlof wrote:
               | It's more useful to fix the problem before it happens.
               | Try to set up systems or workflows that make it easy to
               | do the right thing, rather than trying to fix it
               | afterwards.
        
           | pluijzer wrote:
           | You can try and talk to your developers with more respect.
           | People make mistakes and don't have to be idiots or stupid
           | for it.
           | 
           | edit: mistakes happen always it is better to change the
           | workflow in such a way that a the consequences can be
           | contained.
        
             | chasil wrote:
             | They quit far too much for any rapport.
             | 
             | I have to walk them through configuring an ssh agent
             | (usually devolving to pageant.exe) and they are gone in
             | three months.
             | 
             | Kind of a big ask.
             | 
             | EDIT: I do love my job. People? Uh...
        
               | paraknight wrote:
               | "If everywhere you go smells like shit, maybe it's time
               | to check your own shoes"
        
               | electrondood wrote:
               | > They quit far too much for any rapport.
               | 
               | The developers you publicly describe as stupid and idiots
               | seem to leave every three months. Huh.
        
           | orf wrote:
           | Fix whatever processes, tooling, culture or training _you_
           | have that leads _your_ developers to make these mistakes
        
           | sxg wrote:
           | Multiple people committing the same mistake is much more
           | likely to be a systems problem rather than an individual
           | developer's problem.
           | 
           | The other reply comments are saying the same thing, but your
           | (parent) comment needs to be called out.
        
             | [deleted]
        
           | lstamour wrote:
           | Stop using any passwords that get checked in. Set expiry
           | dates for access tokens. Set up git commit hooks that scan
           | for password or API key prefixes and block the commit. Set up
           | appropriate .gitignore files, you can place them in
           | subfolders to keep them simple.
           | 
           | If possible, switch from using passwords or tokens without
           | expiry to using ephemeral or time-limited tokens such as
           | machine or pod identities, JWT tokens, IAM service accounts,
           | public/private key pairs (if you can get by with only a
           | public key in the repo) or two-factor authentication.
           | Consider distributing time-limited passwords with Hashicorp
           | Vault.
           | 
           | Some teams might use a cloud-hosted secrets manager or
           | password manager like 1password to distribute passwords and
           | then have code load the password as it runs on a developer
           | machine. GitHub has a secrets scanner, if you pay them enough
           | money for "Advanced Security" such that secrets can never be
           | pushed upstream if recognized as such.
           | 
           | Also, converting from any repo format to another repo format
           | requires care and multiple repeated attempts. A lot can go
           | wrong. Reposurgeon (from a sibling comment) is highly
           | recommended but also not easy to use. It takes a lot of
           | attention to detail to really get the details right.
        
             | User23 wrote:
             | Git filter-branch will erase your shame. But as others have
             | said, those credentials are burnt and need to be treated
             | accordingly.
        
               | CrazyPyroLinux wrote:
               | These days https://github.com/newren/git-filter-repo is
               | superior.
        
             | chasil wrote:
             | Just kill me now.
             | 
             | We had the same problem in TFS.
             | 
             | I found them, I warned them, my riot got us kicked off our
             | shared server.
             | 
             | We migrated to our corporate TFS cloud, and they kicked us
             | off for precisely the same reason.
             | 
             | This just won't/can't stop.
        
           | tigerlily wrote:
           | Don't use cvsconvert. Use reposurgeon, you will get much more
           | fine grained control.
           | 
           | Here's a brief precis on getting started: https://gist.github
           | .com/ryfactor/f70529438f254d44c0077176508...
        
             | chasil wrote:
             | I don't think that we will move, and I likely will not
             | assume TFS, but I will look.
        
         | garyrob wrote:
         | I'll look into that, thanks!
        
         | garyrob wrote:
         | I'm going to think about this more. Ironically, I'm in a
         | situation for a few days where I can't really focus on
         | technology.
         | 
         | It sounds like switch and/or restore are probably stable enough
         | that they could be used instead of checkout for the specific
         | tasks I'm trying to do in the blog post, so yet another update
         | will be warranted when I get a chance!
         | 
         | It's completely usable as-is, so I hope no one is scared off by
         | thinking it should incorporate switch and/or restore. It's
         | usable now, and if you do feel like saving a link to it for
         | future reference, I expect that there will be another way in
         | the future to do a couple of the tasks using the more modern
         | syntax.
        
         | malkia wrote:
         | First of all, I'm long time going git n00b (still mainly p4,
         | and g4 for a bit user), but welcome any hints to easy going
         | with git (have to use it occassionally).
         | 
         | Saw this though for switch/restore:
         | 
         | "THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE."
        
           | ilyagr wrote:
           | I, personally, learned to use git a couple of years ago, have
           | never learned to use the `checkout` command, and had no need
           | for it. The goal of `switch`/`restore` is to do everything
           | that `checkout` does while being less of a confusing mess.
           | 
           | See also the reddit thread linked by a nephew comment.
        
           | garyrob wrote:
           | Hmm, maybe I should leave as-is, for the time being, anyway!
           | Thank you!
           | 
           | Update: based on other comments, I WILL seriously look into
           | replacing the use of checkout. It sounds like these newer
           | features are probably stable enough for the simple things
           | that are being done in the blog post, and that updating the
           | post will more it a bit more useful as a starting point for
           | learning git.
           | 
           | I'm thinking of posting the modern syntax as an alternative
           | rather than a replacement to checkout, but I have yet to
           | investigate how stable things are now... will do when I have
           | time.
           | 
           | But meanwhile, the checkout method is fine, it works, and
           | it's well-established for many years.
        
             | NoahKAndrews wrote:
             | I think this Reddit comment has the right idea, especially
             | now that those commands have been released for 3 years: htt
             | ps://www.reddit.com/r/git/comments/ifkbfz/comment/g2on6yo..
             | .
        
               | malkia wrote:
               | Thank you, and that's a good advice from the comment:
               | 
               | "So if you're writing a script that needs to work with
               | dozens of past and future Git versions, use git checkout.
               | If you need to teach humans how to talk to Git, use git
               | switch. Some details of some flags may change in the
               | future, but I'd argue that that'll be a smaller mental
               | challenge than trying to teach which parts of git
               | checkout do what."
               | 
               | I'll try to use more switch/restore
               | 
               | I've actually used "git stash" more than it should be
               | (I'm probably applying real bad "p4/g4/svn" like ideas in
               | my head to the development. As soon as I go into project
               | with few more people, and I'm lost, though I was able to
               | make few PR's in github for things - but everytime had to
               | le-learn the process).
        
               | ziml77 wrote:
               | I sometimes use git stash as a safer alternative to git
               | reset --hard HEAD. git stash -> check that the state
               | you've reverted to is actually what you want -> git stash
               | drop. And since internally stash is just creating a
               | commit, it's even possible to recover the changes if they
               | haven't been garbage collected.
        
               | noSyncCloud wrote:
               | Only used Git and SVN before, sorry for noob question. I
               | guess p4 is Perforce, but what is g4?
        
         | wizofaus wrote:
         | I only found out about git switch recently - super handy when
         | you want to checkout another dev's branch that isn't tracked
         | locally yet. There's a case to be made for reserving 'checkout'
         | for when you specify a filespec rather than a branch.
        
       ___________________________________________________________________
       (page generated 2022-08-06 23:00 UTC)