diff --git a/.gitignore b/.gitignore index f274b4d7..2075e1c8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,10 @@ -# NPM +# NPM and Yarn npm-debug.log +yarn-error.log node_modules/ # Build artifacts and asset stuff build/* -build/bundle.js -build/bundle.*.js -build/main.*.css screens FontAwesome-Vectors.pdf index.html @@ -14,6 +12,9 @@ index.html # Vim swaps *.sw* +# sed backups +*.bak + # Annoying mac stuff .DS_STORE @@ -22,7 +23,6 @@ index.html *.xcworkspace xcuserdata UserInterfaceState.xcuserstate -xcuserdata/ *.pbxuser *.perspective @@ -40,7 +40,6 @@ xcuserdata/ .User.xcconfig -xcuserdata Tools/xctool/build Tools/clang/analyzer/build Tools/clang/libtooling/build @@ -50,7 +49,3 @@ VendorLib/Breakpad/src/tools/mac/dump_syms/build DerivedData VendorLib/clang/lib/arc VendorLib/clang/lib/c++ - -*.swp - - diff --git a/.gitpod.yml b/.gitpod.yml new file mode 100644 index 00000000..7e9d9b83 --- /dev/null +++ b/.gitpod.yml @@ -0,0 +1,9 @@ +ports: +- port: 8000 + onOpen: open-preview +tasks: +- init: yarn install + command: > + yarn gulp fastBuild && + printf "\nWelcome to Learn Git Branching\nTo rebuild the app, simply run 'yarn gulp fastBuild' and reload index.html.\n\n" && + python3 -m http.server 8000 2>/dev/null diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 00000000..94ef1d9a --- /dev/null +++ b/.jshintrc @@ -0,0 +1,41 @@ +{ + "esversion": 6, + "curly": true, + "eqeqeq": false, + "regexp": false, + "nonew": false, + "latedef": false, + "forin": false, + "globalstrict": false, + "node": true, + "immed": true, + "newcap": true, + "noarg": true, + "bitwise": true, + "sub": true, + "undef": true, + "unused": true, + "trailing": true, + "devel": true, + "jquery": true, + "nonstandard": true, + "boss": true, + "eqnull": true, + "browser": true, + "debug": true, + "globals": { + "casper": true, + "Raphael": true, + "require": true, + "console": true, + "describe": true, + "expect": true, + "it": true, + "runs": true, + "waitsFor": true, + "exports": true, + "module": true, + "prompt": true, + "process": true + } +} diff --git a/.travis.yml b/.travis.yml index 89b60a3b..3b6b4d6f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,16 @@ +sudo: false language: node_js node_js: - - "4.1" - - "5.3" + - "10" + - "8" +before_install: + - curl -o- -L https://yarnpkg.com/install.sh | bash + - export PATH="$HOME/.yarn/bin:$PATH" +cache: + yarn: true + directories: + - "node_modules" +script: + - ./checkgit.sh "Source files were modified before build; is yarn.lock out of sync with package.json?" || travis_terminate $? + - yarn gulp + - ./checkgit.sh "Source files were modified by the build" || travis_terminate $? diff --git a/Gruntfile.js b/Gruntfile.js deleted file mode 100644 index 13e7f6b8..00000000 --- a/Gruntfile.js +++ /dev/null @@ -1,256 +0,0 @@ -var _ = require('underscore'); -var fs = require('fs'); - -// Haha, this is so tricky. so we have a template for index.html to stick -// in the hashed JS and style files -- that template also contains -// templates used in the app. in order to avoid evaluating those -// templates, we change the regexes so we can effectively nest templates -_.templateSettings.interpolate = /\{\{(.+?)\}\}/g; -_.templateSettings.escape = /\{\{\{(.*?)\}\}\}/g; -_.templateSettings.evaluate = /\{\{-(.*?)\}\}/g; - -// precompile for speed -var indexFile = fs.readFileSync('src/template.index.html').toString(); -var indexTemplate = _.template(indexFile); - -/** - * This is SUPER jank but I cant get the underscore templating to evaluate - * correctly with custom regexes, so I'm just going to use interpolate - * and define the strings here. - */ - -var prodDependencies = [ - '', - '', - '', - '' -]; - -var devDependencies = [ - '', - '', - '', - '' -]; - -/*global module:false*/ -module.exports = function(grunt) { - // eventually have sound...? - grunt.registerTask('compliment', 'Stay motivated!', function() { - var compliments = grunt.config('compliment.compliments'); - var index = Math.floor(Math.random() * compliments.length); - - grunt.log.writeln(compliments[index]); - }); - - grunt.registerTask('lintStrings', 'Find if an INTL string doesnt exist', function() { - var child_process = require('child_process'); - child_process.exec('node src/js/intl/checkStrings', function(err, output) { - grunt.log.writeln(output); - }); - }); - - var buildIndex = function(config) { - grunt.log.writeln('Building index...'); - - // first find the one in here that we want - var buildFiles = fs.readdirSync('build'); - - var hashedMinFile; - if (buildFiles.length == 2) { - grunt.log.writeln('Assuming debug mode wanted'); - hashedMinFile = 'bundle.js'; - } - var jsRegex = /bundle\.min\.\w+\.js/; - _.each(buildFiles, function(jsFile) { - if (jsRegex.test(jsFile)) { - if (hashedMinFile) { - throw new Error('more than one hashed file: ' + jsFile + hashedMinFile); - } - hashedMinFile = jsFile; - } - }); - if (!hashedMinFile) { throw new Error('no hashed min file found!'); } - - grunt.log.writeln('Found hashed js file: ' + hashedMinFile); - - var styleRegex = /main\.\w+\.css/; - var hashedStyleFile; - _.each(buildFiles, function(styleFile) { - if (styleRegex.test(styleFile)) { - if (hashedStyleFile) { - throw new Error('more than one hashed style: ' + styleFile + hashedStyleFile); - } - hashedStyleFile = styleFile; - } - }); - if (!hashedStyleFile) { throw new Error('no style found'); } - - grunt.log.writeln('Found hashed style file: ' + hashedStyleFile); - - // output these filenames to our index template - var outputIndex = indexTemplate({ - jsFile: hashedMinFile, - styleFile: hashedStyleFile, - jsDependencies: config.isProd ? - prodDependencies.join("\n") : - devDependencies.join("\n") - }); - fs.writeFileSync('index.html', outputIndex); - }; - - grunt.registerTask('buildIndex', 'stick in hashed resources', buildIndex.bind(null, {isProd: true})); - grunt.registerTask('buildIndexDev', 'stick in hashed resources', buildIndex.bind(null, {isProd: false})); - - grunt.initConfig({ - pkg: grunt.file.readJSON('package.json'), - jshint: { - all: [ - 'Gruntfile.js', - '__tests__/*.spec.js', - 'src/js/**/*.js', - 'src/js/**/**/*.js', - 'src/levels/**/*.js' - ], - options: { - ignores: [ - 'src/js/**/*.ios.js', - 'src/js/native_react_views/*.js' - ], - curly: true, - // sometimes triple equality is just redundant and unnecessary - eqeqeq: false, - // i know my regular expressions - regexp: false, - // i think it's super weird to not use new on a constructor - nonew: false, - // these latedefs are just annoying -- no pollution of global scope - latedef: false, - // use this in mocks - forin: false, - // This gets annoying - globalstrict: false, - // for use strict warnings - node: true, - /////////////////////////////// - // All others are true - ////////////////////////////// - immed: true, - newcap: true, - noarg: true, - bitwise: true, - sub: true, - undef: true, - unused: false, - trailing: true, - devel: true, - jquery: true, - nonstandard: true, - boss: true, - eqnull: true, - browser: true, - debug: true, - reporterOutput: '', - globals: { - casper: true, - Raphael: true, - require: true, - console: true, - describe: true, - expect: true, - it: true, - runs: true, - waitsFor: true, - exports: true, - module: true, - prompt: true, - process: true - } - }, - }, - compliment: { - compliments: [ - "Wow peter great work!", - "Such a professional dev environment", - "Can't stop the TRAIN", - "git raging" - ] - }, - hash: { - options: { - mapping: '' - }, - js: { - src: 'build/bundle.min.js', - dest: 'build/' - }, - css: { - src: 'src/style/main.css', - dest: 'build/' - } - }, - watch: { - files: '', - tasks: 'watching' - }, - uglify: { - build: { - src: ['build/bundle.js'], - dest: 'build/bundle.min.js' - } - }, - clean: ['build/*'], - shell: { - gitAdd: { - command: 'git add build/' - } - }, - jasmine_node: { - projectRoot: './__tests__/', - forceExit: true, - verbose: true, - requirejs: false - }, - env: { - prod: { - NODE_ENV: 'production', - }, - }, - browserify: { - options: { - transform: [require('grunt-react').browserify] - }, - dist: { - files: { - 'build/bundle.js': [ - 'src/**/*.js', - 'src/**/*.jsx' - ] - } - } - } - }); - - // all my npm helpers - grunt.loadNpmTasks('grunt-jsxhint'); - grunt.loadNpmTasks('grunt-browserify'); - grunt.loadNpmTasks('grunt-hash'); - grunt.loadNpmTasks('grunt-contrib-clean'); - grunt.loadNpmTasks('grunt-shell-spawn'); - grunt.loadNpmTasks('grunt-jasmine-node'); - grunt.loadNpmTasks('grunt-contrib-uglify'); - grunt.loadNpmTasks('grunt-react'); - grunt.loadNpmTasks('grunt-env'); - - grunt.registerTask('build', - ['clean', 'env', 'browserify', 'uglify', 'hash', 'buildIndex', 'shell:gitAdd', 'jasmine_node', 'jshint', 'lintStrings', 'compliment'] - ); - grunt.registerTask('lint', ['jshint', 'compliment']); - grunt.registerTask('fastBuild', ['clean', 'browserify', 'hash', 'buildIndexDev', 'jshint']); - grunt.registerTask('watching', ['fastBuild', 'jasmine_node', 'jshint', 'lintStrings']); - - grunt.registerTask('default', ['build']); - grunt.registerTask('test', ['jasmine_node']); - grunt.registerTask('casperTest', ['shell:casperTest']); -}; - diff --git a/README.md b/README.md index b19d022b..38a4dd3b 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ # LearnGitBranching [![Build Status](https://travis-ci.org/pcottle/learnGitBranching.svg?branch=master)](https://travis-ci.org/pcottle/learnGitBranching) +[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?)](https://github.com/pcottle/learnGitBranching/pulls) -LearnGitBranching is a git repository visualizer, sandbox, and series of educational tutorials and challenges. Its primary purpose is to help developers understand git through the power of visualization (something that's absent when working on the command line). +LearnGitBranching is a git repository visualizer, sandbox, and a series of educational tutorials and challenges. Its primary purpose is to help developers understand git through the power of visualization (something that's absent when working on the command line). This is achieved through a game with different levels to get acquainted with the different git commands. You can input a variety of commands into LearnGitBranching (LGB) -- as commands are processed, the nearby commit tree will dynamically update to reflect the effects of each command: @@ -11,7 +12,7 @@ You can input a variety of commands into LearnGitBranching (LGB) -- as commands This visualization combined with tutorials and "levels" can help both beginners and intermediate developers polish their version control skills. A quick demo is available here: https://pcottle.github.com/learnGitBranching/?demo -Or you can launch the application normally here: +Or, you can launch the application normally here: https://pcottle.github.com/learnGitBranching/ ### Sandbox Mode @@ -69,34 +70,73 @@ Thus, if you build the app locally, all you have to do in order to run the app i ## Building yourself / Contributing Functionality For contributing core functionality in the app, you'll probably want to test your changes -at least once before submitting a pull request. That means you'll need the "Grunt.js" build tool to build the app: +at least once before submitting a pull request. That means you'll need the "gulp.js" build tool to build the app: -https://gruntjs.com/getting-started +https://gulpjs.com/docs/en/getting-started/quick-start -You'll also need `npm` to download all the dependencies of the project. +You'll also need `yarn` to download all the dependencies of the project. The general workflow / steps are below: -``` +```bash git clone cd learnGitBranching -npm install # to install all the node modules I depend on +yarn install git checkout -b newAwesomeFeature vim ./src/js/git/index.js # some changes -grunt fastBuild # skips tests and linting, faster build +yarn gulp fastBuild # skips tests and linting, faster build # after building you can open up your browser to the index.html # file generated and see your changes vim ./src/js/git/index.js # more changes -grunt build # runs tests and lint +yarn gulp build # runs tests and lint git commit -am "My new sweet feature!" git push # go online and request a pull ``` +Alternatively, you can also build and run the app in a pre-configured online workspace: + +[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/pcottle/learnGitBranching/blob/master/src/js/git/index.js) + +[//]: contributor-faces + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[//]: contributor-faces + ## Helpful Folks A big shoutout to these brave souls for extensively testing our sandbox and finding bugs and/or inconsistencies: @@ -122,7 +162,9 @@ And the following heroes for assisting in translating: * Vasil Kulakov ("coyl") & Lyubov Agadjanyan ("shayenblue") * Aliaksei Berkau ("alexeiberkov") * Mizunashi Mana ("mizunashi-mana") +* Olsza Also huge shoutout for everyone who has put up a pull request that was pulled! Check out the 30+ contributors we have in the [Contributors View](https://github.com/pcottle/learnGitBranching/graphs/contributors) And everyone who has reported an issue that was successfully closed! + diff --git a/__tests__/base.js b/__tests__/base.js index a8d5ab32..dc0fc848 100644 --- a/__tests__/base.js +++ b/__tests__/base.js @@ -1,3 +1,5 @@ +var Q = require('q'); + var HeadlessGit = require('../src/js/git/headless').HeadlessGit; var TreeCompare = require('../src/js/graph/treeCompare.js'); @@ -26,65 +28,27 @@ var getHeadlessSummary = function(headless) { var expectLevelAsync = function(headless, levelBlob) { var command = levelBlob.solutionCommand; if (command.indexOf('git rebase -i') !== -1) { - // dont do interactive rebase levels + // don't do interactive rebase levels return; } - var hasWarned = false; - var start; - runs(function() { - start = Date.now(); - headless.sendCommand(command); + return headless.sendCommand(command).then(function() { + expect(compareLevelTree(headless, levelBlob)).toBeTruthy( + 'Level "' + levelBlob['name']['en_US'] + '" should get solved' + ); }); - waitsFor(function() { - var diff = (Date.now() - start); - if (diff > TIME - 10 && !hasWarned) { - hasWarned = true; - console.log('this goal tree', loadTree(levelBlob.goalTreeString)); - console.log('not going to match with command', command); - console.log(getHeadlessSummary(headless)); - } - var result = compareLevelTree(headless, levelBlob); - if (result) { - console.log('solved level ' + levelBlob.name.en_US); - } - return result; - }, 'trees should be equal', TIME); }; var expectTreeAsync = function(command, expectedJSON, startJSON) { var headless = new HeadlessGit(); - var start = Date.now(); - var haveReported = false; if (startJSON) { headless.gitEngine.loadTreeFromString(startJSON); } - runs(function() { - headless.sendCommand(command); + return headless.sendCommand(command).then(function() { + expect(compareAnswer(headless, expectedJSON)).toBeTruthy(); }); - waitsFor(function() { - var diff = (Date.now() - start); - if (diff > TIME - 40 && !haveReported) { - haveReported = true; - var expected = loadTree(expectedJSON); - console.log('not going to match', command); - console.log('expected\n>>>>>>>>\n', expected); - console.log('\n<<<<<<<<<<<\nactual', getHeadlessSummary(headless)); - console.log('\n<<<>>>>\n'); - if (expected.originTree) { - console.log('expected origin tree:'); - console.log(expected.originTree); - console.log('\n=========\n'); - console.log('actual origin tree'); - console.log(getHeadlessSummary(headless).originTree); - } - console.log(expectedJSON); - console.log(JSON.stringify(getHeadlessSummary(headless))); - } - return compareAnswer(headless, expectedJSON); - }, 'trees should be equal', 500); }; var expectLevelSolved = function(levelBlob) { @@ -95,6 +59,19 @@ var expectLevelSolved = function(levelBlob) { expectLevelAsync(headless, levelBlob); }; +var runCommand = function(command, resultHandler) { + var headless = new HeadlessGit(); + var deferred = Q.defer(); + var msg = null; + + return headless.sendCommand(command, deferred).then(function() { + return deferred.promise.then(function(commands) { + msg = commands[commands.length - 1].get('error').get('msg'); + resultHandler(msg); + }); + }); +}; + var TIME = 150; // useful for throwing garbage and then expecting one commit var ONE_COMMIT_TREE = '{"branches":{"master":{"target":"C2","id":"master"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"}}'; @@ -105,6 +82,6 @@ module.exports = { TIME: TIME, expectTreeAsync: expectTreeAsync, expectLevelSolved: expectLevelSolved, - ONE_COMMIT_TREE: ONE_COMMIT_TREE + ONE_COMMIT_TREE: ONE_COMMIT_TREE, + runCommand: runCommand }; - diff --git a/__tests__/git.spec.js b/__tests__/git.spec.js index 25f55f96..cfe6317d 100644 --- a/__tests__/git.spec.js +++ b/__tests__/git.spec.js @@ -1,279 +1,426 @@ +var intl = require('../src/js/intl') var base = require('./base'); var expectTreeAsync = base.expectTreeAsync; +var runCommand = base.runCommand; describe('Git', function() { it('Commits', function() { - expectTreeAsync( + return expectTreeAsync( 'git commit', base.ONE_COMMIT_TREE ); }); it('handles commit options', function() { - expectTreeAsync( + return expectTreeAsync( 'git commit; git commit --amend;', '%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C2%27%22%2C%22id%22%3A%22master%22%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C2%27%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%7D' ); }); it('throws with bad arg options', function() { - expectTreeAsync( + return expectTreeAsync( 'git commit foo; git commit -am -m; git commit -am -a; git commit -am "hi" "ho"; git commit', base.ONE_COMMIT_TREE ); }); it('handles lower case branch options', function() { - expectTreeAsync( + return expectTreeAsync( 'git branch banana c0; git commit; git checkout -b side banana; git branch -d banana;git branch -f another c1; git commit', '{"branches":{"master":{"target":"C2","id":"master"},"side":{"target":"C3","id":"side"},"another":{"target":"C1","id":"another"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C0"],"id":"C3"}},"HEAD":{"target":"side","id":"HEAD"}}' ); }); it('handles branch options', function() { - expectTreeAsync( + return expectTreeAsync( 'git branch banana C0; git commit; git checkout -b side banana; git branch -d banana;git branch -f another C1; git commit', '{"branches":{"master":{"target":"C2","id":"master"},"side":{"target":"C3","id":"side"},"another":{"target":"C1","id":"another"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C0"],"id":"C3"}},"HEAD":{"target":"side","id":"HEAD"}}' ); }); it('does add', function() { - expectTreeAsync( + return expectTreeAsync( 'git add; git commit', base.ONE_COMMIT_TREE ); }); it('resets with all options', function() { - expectTreeAsync( + return expectTreeAsync( 'git commit;git reset --soft HEAD~1;git reset --hard HEAD~1;gc;go C1;git reset --hard C3;', '{"branches":{"master":{"target":"C3","id":"master"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C1"],"id":"C3"}},"HEAD":{"target":"C1","id":"HEAD"}}' ); }); it('Checkouts', function() { - expectTreeAsync( + return expectTreeAsync( 'git checkout -b side', '{"branches":{"master":{"target":"C1","id":"master"},"side":{"target":"C1","id":"side"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"side","id":"HEAD"}}' ); }); + it('Switches', function() { + return expectTreeAsync( + 'git switch -c side', + '{"branches":{"master":{"target":"C1","id":"master"},"side":{"target":"C1","id":"side"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"side","id":"HEAD"}}' + ); + }); + it('Rebases', function() { - expectTreeAsync( + return expectTreeAsync( 'gc; git checkout -b side C1; gc; git rebase master', '%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C2%22%2C%22id%22%3A%22master%22%7D%2C%22side%22%3A%7B%22target%22%3A%22C3%27%22%2C%22id%22%3A%22side%22%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22side%22%2C%22id%22%3A%22HEAD%22%7D%7D' ); }); it('Interactive rebase', function() { - expectTreeAsync( + return expectTreeAsync( 'gc; git checkout -b side C1; gc; git rebase -i master --interactive-test', '%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C2%22%2C%22id%22%3A%22master%22%7D%2C%22side%22%3A%7B%22target%22%3A%22C3%27%22%2C%22id%22%3A%22side%22%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22side%22%2C%22id%22%3A%22HEAD%22%7D%7D' ); }); it('Interactive rebases with commit re-ordering', function() { - expectTreeAsync( - 'gc;gc;git rebase -i C0 --interactive-test C3,C1', + return expectTreeAsync( + 'gc;gc;git rebase -i C0 --interactive-test C3,C1', '%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C1%27%22%2C%22id%22%3A%22master%22%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C3%27%22%7D%2C%22C1%27%22%3A%7B%22parents%22%3A%5B%22C3%27%22%5D%2C%22id%22%3A%22C1%27%22%7D%7D%2C%22tags%22%3A%7B%7D%2C%22HEAD%22%3A%7B%22id%22%3A%22HEAD%22%2C%22target%22%3A%22master%22%7D%7D' - ); - }); + ); + }); it('Switch branch and execute interactive rebase', function() { - expectTreeAsync( - 'git branch test;git rebase -i C0 test --interactive-test', + return expectTreeAsync( + 'git branch test;git rebase -i C0 test --interactive-test', '%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C1%22%2C%22id%22%3A%22master%22%7D%2C%22test%22%3A%7B%22target%22%3A%22C1%27%22%2C%22id%22%3A%22test%22%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C1%27%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%27%22%7D%7D%2C%22tags%22%3A%7B%7D%2C%22HEAD%22%3A%7B%22id%22%3A%22HEAD%22%2C%22target%22%3A%22test%22%7D%7D' - ); - }); + ); + }); it('Reverts', function() { - expectTreeAsync( + return expectTreeAsync( 'git revert HEAD', '%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C1%27%22%2C%22id%22%3A%22master%22%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C1%27%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C1%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%7D' ); }); it('Merges', function() { - expectTreeAsync( + return expectTreeAsync( 'gc; git checkout -b side C1; gc; git merge master', '{"branches":{"master":{"target":"C2","id":"master"},"side":{"target":"C4","id":"side"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C1"],"id":"C3"},"C4":{"parents":["C2","C3"],"id":"C4"}},"HEAD":{"target":"side","id":"HEAD"}}' ); }); it('Resets', function() { - expectTreeAsync( + return expectTreeAsync( 'git commit; git reset HEAD~1', '{"branches":{"master":{"target":"C1","id":"master"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"}}' ); }); it('Branches', function() { - expectTreeAsync( + return expectTreeAsync( 'git branch side C0', '{"branches":{"master":{"target":"C1","id":"master"},"side":{"target":"C0","id":"side"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"}}' ); }); it('Branches lowercase', function() { - expectTreeAsync( + return expectTreeAsync( 'git branch side c0', '{"branches":{"master":{"target":"C1","id":"master"},"side":{"target":"C0","id":"side"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"}}' ); }); it('Deletes branches', function() { - expectTreeAsync( + return expectTreeAsync( 'git branch side; git branch -d side', '{"branches":{"master":{"target":"C1","id":"master"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"}}' ); }); - it('Ammends commits', function() { - expectTreeAsync( + it('Amends commits', function() { + return expectTreeAsync( 'git commit --amend', '%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C1%27%22%2C%22id%22%3A%22master%22%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C1%27%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%7D' ); }); it('Cherry picks', function() { - expectTreeAsync( + return expectTreeAsync( 'git checkout -b side C0; gc; git cherry-pick C11; git cherry-pick C1', '%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C1%22%2C%22id%22%3A%22master%22%7D%2C%22side%22%3A%7B%22target%22%3A%22C1%27%22%2C%22id%22%3A%22side%22%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C1%27%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C1%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22side%22%2C%22id%22%3A%22HEAD%22%7D%7D' ); }); + it('Range operator is not supported', function() { + return expectTreeAsync( + 'git checkout -b side C0; git cherry-pick C1..C0', + '{"branches":{"master":{"target": "C1","id": "master"},"side":{"target":"C0","id": "side"}},"commits":{"C0":{"parents":[],"id": "C0","rootCommit": true},"C1":{"parents":["C0"],"id": "C1"}},"HEAD":{"id": "HEAD","target":"side"}}' + ); + }); + it('Forces branches', function() { - expectTreeAsync( + return expectTreeAsync( 'git checkout -b side; git branch -f side C0', '{"branches":{"master":{"target":"C1","id":"master"},"side":{"target":"C0","id":"side"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"side","id":"HEAD"}}' ); }); it('Rebases only new commits to destination', function() { - expectTreeAsync( + return expectTreeAsync( 'git checkout -b side C0; gc; gc;git cherry-pick C1;git rebase master', '%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C1%22%2C%22id%22%3A%22master%22%7D%2C%22side%22%3A%7B%22target%22%3A%22C3%27%22%2C%22id%22%3A%22side%22%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C1%27%22%3A%7B%22parents%22%3A%5B%22C3%22%5D%2C%22id%22%3A%22C1%27%22%7D%2C%22C2%27%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%27%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C2%27%22%5D%2C%22id%22%3A%22C3%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22side%22%2C%22id%22%3A%22HEAD%22%7D%7D' ); }); it('checks out after a rebase', function() { - expectTreeAsync( + return expectTreeAsync( 'git commit; git checkout -b bugFix C1; git commit; git rebase master;git checkout master', '%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C2%22%2C%22id%22%3A%22master%22%7D%2C%22bugFix%22%3A%7B%22target%22%3A%22C3%27%22%2C%22id%22%3A%22bugFix%22%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%7D' ); }); + it('switches after a rebase ', function() { + return expectTreeAsync( + 'git commit; git switch -c bugFix C1; git commit; git rebase master;git switch master', + '%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C2%22%2C%22id%22%3A%22master%22%7D%2C%22bugFix%22%3A%7B%22target%22%3A%22C3%27%22%2C%22id%22%3A%22bugFix%22%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%7D' + ); + }); + it('checks out after an interactive rebase', function() { - expectTreeAsync( + return expectTreeAsync( 'git commit; git checkout -b bugFix C1; git commit; git rebase -i master --interactive-test;git checkout master', '%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C2%22%2C%22id%22%3A%22master%22%7D%2C%22bugFix%22%3A%7B%22target%22%3A%22C3%27%22%2C%22id%22%3A%22bugFix%22%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%7D' ); }); it('solves merging level', function() { - expectTreeAsync( + return expectTreeAsync( 'git checkout -b bugFix;git commit;git checkout master;git commit;git merge bugFix', - '{"branches":{"master":{"target":"C1","id":"master"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"}}' + '%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C4%22%2C%22id%22%3A%22master%22%2C%22remoteTrackingBranchID%22%3Anull%7D%2C%22bugFix%22%3A%7B%22target%22%3A%22C2%22%2C%22id%22%3A%22bugFix%22%2C%22remoteTrackingBranchID%22%3Anull%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C4%22%3A%7B%22parents%22%3A%5B%22C2%22%2C%22C3%22%5D%2C%22id%22%3A%22C4%22%7D%7D%2C%22tags%22%3A%7B%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%7D' ); }); it('solves rebase level', function() { - expectTreeAsync( + return expectTreeAsync( 'git checkout -b bugFix;git commit;git checkout master;git commit;git checkout bugFix;git rebase master', - '{"branches":{"master":{"target":"C1","id":"master"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"}}' + '%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C3%22%2C%22id%22%3A%22master%22%2C%22remoteTrackingBranchID%22%3Anull%7D%2C%22bugFix%22%3A%7B%22target%22%3A%22C2%27%22%2C%22id%22%3A%22bugFix%22%2C%22remoteTrackingBranchID%22%3Anull%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C2%27%22%3A%7B%22parents%22%3A%5B%22C3%22%5D%2C%22id%22%3A%22C2%27%22%7D%7D%2C%22tags%22%3A%7B%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22bugFix%22%2C%22id%22%3A%22HEAD%22%7D%7D' ); }); it('solves rebase level with interactive rebase', function() { - expectTreeAsync( + return expectTreeAsync( 'git checkout -b bugFix;git commit;git checkout master;git commit;git checkout bugFix;git rebase -i master --interactive-test', - '{"branches":{"master":{"target":"C1","id":"master"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"}}' + '%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C3%22%2C%22id%22%3A%22master%22%2C%22remoteTrackingBranchID%22%3Anull%7D%2C%22bugFix%22%3A%7B%22target%22%3A%22C2%27%22%2C%22id%22%3A%22bugFix%22%2C%22remoteTrackingBranchID%22%3Anull%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C2%27%22%3A%7B%22parents%22%3A%5B%22C3%22%5D%2C%22id%22%3A%22C2%27%22%7D%7D%2C%22tags%22%3A%7B%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22bugFix%22%2C%22id%22%3A%22HEAD%22%7D%7D' ); }); it('does a whole bunch of crazy merging', function() { - expectTreeAsync( + return expectTreeAsync( 'gc;go -b side C1;gc;git merge master;go -b bug master;gc;go -b wut C3;git rebase bug;go side;git rebase wut;gc;git rebase wut;git merge C4;go master;git rebase side;go C6;git merge C3\';gb -f wut C8;go bug;git rebase wut', '%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C7%22%2C%22id%22%3A%22master%22%7D%2C%22side%22%3A%7B%22target%22%3A%22C7%22%2C%22id%22%3A%22side%22%7D%2C%22bug%22%3A%7B%22target%22%3A%22C8%22%2C%22id%22%3A%22bug%22%7D%2C%22wut%22%3A%7B%22target%22%3A%22C8%22%2C%22id%22%3A%22wut%22%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C4%22%3A%7B%22parents%22%3A%5B%22C2%22%2C%22C3%22%5D%2C%22id%22%3A%22C4%22%7D%2C%22C5%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C5%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C5%22%5D%2C%22id%22%3A%22C3%27%22%7D%2C%22C6%22%3A%7B%22parents%22%3A%5B%22C4%22%5D%2C%22id%22%3A%22C6%22%7D%2C%22C6%27%22%3A%7B%22parents%22%3A%5B%22C3%27%22%5D%2C%22id%22%3A%22C6%27%22%7D%2C%22C7%22%3A%7B%22parents%22%3A%5B%22C4%22%2C%22C6%27%22%5D%2C%22id%22%3A%22C7%22%7D%2C%22C8%22%3A%7B%22parents%22%3A%5B%22C3%27%22%2C%22C6%22%5D%2C%22id%22%3A%22C8%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22bug%22%2C%22id%22%3A%22HEAD%22%7D%7D' ); }); it('if no-ff is specified, will always make a merge commit', function() { - expectTreeAsync( + return expectTreeAsync( 'git commit; go -b side HEAD~1; git commit; git merge master; go master; git merge side --no-ff', '{"branches":{"master":{"target":"C5","id":"master","remoteTrackingBranchID":null},"side":{"target":"C4","id":"side","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C1"],"id":"C3"},"C4":{"parents":["C2","C3"],"id":"C4"},"C5":{"parents":["C2","C4"],"id":"C5"}},"HEAD":{"target":"master","id":"HEAD"}}' ); }); - it('makes a tag', function() { - expectTreeAsync( - 'git tag v1', - '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"tags":{"v1":{"target":"C1","id":"v1","type":"tag"}},"HEAD":{"target":"master","id":"HEAD"}}' - ); - }); + it('makes a tag', function() { + return expectTreeAsync( + 'git tag v1', + '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"tags":{"v1":{"target":"C1","id":"v1","type":"tag"}},"HEAD":{"target":"master","id":"HEAD"}}' + ); + }); - it('makes a tag on another ref', function() { - expectTreeAsync( - 'git tag v1 C0', - '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"tags":{"v1":{"target":"C0","id":"v1","type":"tag"}},"HEAD":{"target":"master","id":"HEAD"}}' - ); - }); + it('makes a tag and removes a tag', function() { + return expectTreeAsync( + 'git tag v1; git tag -d v1', + '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"}}' + ); + }); - it('doesnt make a tag if ref doesnt resolve', function() { - expectTreeAsync( - 'git tag v1 foo', - '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"}}' - ); - }); + it('makes a tag on another ref', function() { + return expectTreeAsync( + 'git tag v1 C0', + '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"tags":{"v1":{"target":"C0","id":"v1","type":"tag"}},"HEAD":{"target":"master","id":"HEAD"}}' + ); + }); - it('makes tag with relative ref and etc', function() { - expectTreeAsync( - 'git tag v1 HEAD~1', - '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"tags":{"v1":{"target":"C0","id":"v1","type":"tag"}},"HEAD":{"target":"master","id":"HEAD"}}' - ); - }); + it('doesn\'t make a tag if ref doesn\'t resolve', function() { + return expectTreeAsync( + 'git tag v1 foo', + '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"}}' + ); + }); - it('makes tag with 3 letters', function() { - expectTreeAsync( - 'git tag foo', - '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"tags":{"foo":{"target":"C1","id":"foo","type":"tag"}},"HEAD":{"target":"master","id":"HEAD"}}' - ); - }); + it('makes tag with relative ref and etc', function() { + return expectTreeAsync( + 'git tag v1 HEAD~1', + '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"tags":{"v1":{"target":"C0","id":"v1","type":"tag"}},"HEAD":{"target":"master","id":"HEAD"}}' + ); + }); - it('does not make tag if ref does not resolve', function() { - expectTreeAsync( - 'git tag foo banana', - '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"}}' - ); - }); + it('makes tag with 3 letters', function() { + return expectTreeAsync( + 'git tag foo', + '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"tags":{"foo":{"target":"C1","id":"foo","type":"tag"}},"HEAD":{"target":"master","id":"HEAD"}}' + ); + }); - it('should respect second command for -B option', function() { - expectTreeAsync( - 'git commit; git checkout -B side C1', - '{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":null},"side":{"target":"C1","id":"side","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"tags":{},"HEAD":{"target":"side","id":"HEAD"}}' - ); - }); + it('does not make tag if ref does not resolve', function() { + return expectTreeAsync( + 'git tag foo banana', + '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"}}' + ); + }); - it('will throw error if bad commits given to interactive test', function() { - expectTreeAsync( - 'gc; git rebase HEAD~2 -i --interactive-test C2,C100; gc', - '{"branches":{"master":{"target":"C3","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C2"],"id":"C3"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"}}' - ); - }); + it('should respect second command for -B option', function() { + return expectTreeAsync( + 'git commit; git checkout -B side C1', + '{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":null},"side":{"target":"C1","id":"side","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"tags":{},"HEAD":{"target":"side","id":"HEAD"}}' + ); + }); - it('can handle slashes and dashes in branch names but doesnt allow o/', function() { - expectTreeAsync( + it('will throw error if bad commits given to interactive test', function() { + return expectTreeAsync( + 'gc; git rebase HEAD~2 -i --interactive-test C2,C100; gc', + '{"branches":{"master":{"target":"C3","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C2"],"id":"C3"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"}}' + ); + }); + + it('can handle slashes and dashes in branch names but doesn\'t allow o/', function() { + return expectTreeAsync( 'git branch foo/bar; git commit; git checkout foo/bar; gc; go master; git merge foo/bar; go foo/bar; git checkout -b bar-baz; git commit; git branch o/foo', '{"branches":{"master":{"target":"C4","id":"master","remoteTrackingBranchID":null},"foo/bar":{"target":"C3","id":"foo/bar","remoteTrackingBranchID":null},"bar-baz":{"target":"C5","id":"bar-baz","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C1"],"id":"C3"},"C4":{"parents":["C2","C3"],"id":"C4"},"C5":{"parents":["C3"],"id":"C5"}},"tags":{},"HEAD":{"target":"bar-baz","id":"HEAD"}}' - ); + ); }); it('the regex allows for multiple dashes but not in a row', function() { - expectTreeAsync( + return expectTreeAsync( 'git branch foo-bar-banana-baz; gc; git branch foo----bar//baz', '{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":null},"foo-bar-b":{"target":"C1","id":"foo-bar-b","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"}}' - ); + ); }); -}); + describe('RevList', function() { + it('requires at least 1 argument', function() { + return runCommand('git rev-list', function(commandMsg) { + expect(commandMsg).toEqual(intl.str( + 'git-error-args-few', + { + lower: 1, + what: 'with git rev-list' + } + )); + }); + }); + + describe('supports', function() { + var SETUP = 'git co -b left C0; gc; git merge master; git co -b right C0; gc; git merge master; git co -b all left; git merge right; '; + + it('single included revision', function() { + return runCommand(SETUP + 'git rev-list all', function(commandMsg) { + expect(commandMsg).toBe('C6\nC5\nC4\nC3\nC2\nC1\nC0\n'); + }); + }); + + it('single excluded revision', function() { + return runCommand(SETUP + 'git rev-list all ^right', function(commandMsg) { + expect(commandMsg).toBe('C6\nC3\nC2\n'); + }); + }); + + it('multiple included revisions', function() { + return runCommand(SETUP + 'git rev-list right left', function(commandMsg) { + expect(commandMsg).toBe('C5\nC4\nC3\nC2\nC1\nC0\n'); + }); + }); + + it('multiple excluded revisions', function() { + return runCommand(SETUP + 'git rev-list all ^right ^left', function(commandMsg) { + expect(commandMsg).toBe('C6\n'); + }); + }); + + it('range between branches', function() { + return runCommand(SETUP + 'git rev-list left..right', function(commandMsg) { + expect(commandMsg).toBe('C5\nC4\n'); + }); + }); + + it('range between commits', function() { + return runCommand(SETUP + 'git rev-list C3..C5', function(commandMsg) { + expect(commandMsg).toBe('C5\nC4\n'); + }); + }); + }); + }); + + describe('Log supports', function() { + var SETUP = 'git co -b left C0; gc; git merge master; git co -b right C0; gc; git merge master; git co -b all left; git merge right; '; + + it('implied HEAD', function() { + return runCommand(SETUP + '; git co right; git log', function(commandMsg) { + expect(commandMsg).toContain('Commit: C0\n'); + expect(commandMsg).toContain('Commit: C1\n'); + expect(commandMsg).not.toContain('Commit: C2\n'); + expect(commandMsg).not.toContain('Commit: C3\n'); + expect(commandMsg).toContain('Commit: C4\n'); + expect(commandMsg).toContain('Commit: C5\n'); + expect(commandMsg).not.toContain('Commit: C6\n'); + }); + }); + + it('single included revision', function() { + return runCommand(SETUP + 'git log right', function(commandMsg) { + expect(commandMsg).toContain('Commit: C0\n'); + expect(commandMsg).toContain('Commit: C1\n'); + expect(commandMsg).not.toContain('Commit: C2\n'); + expect(commandMsg).not.toContain('Commit: C3\n'); + expect(commandMsg).toContain('Commit: C4\n'); + expect(commandMsg).toContain('Commit: C5\n'); + expect(commandMsg).not.toContain('Commit: C6\n'); + }); + }); + + it('single excluded revision', function() { + return runCommand(SETUP + 'git log all ^right', function(commandMsg) { + expect(commandMsg).not.toContain('Commit: C0\n'); + expect(commandMsg).not.toContain('Commit: C1\n'); + expect(commandMsg).toContain('Commit: C2\n'); + expect(commandMsg).toContain('Commit: C3\n'); + expect(commandMsg).not.toContain('Commit: C4\n'); + expect(commandMsg).not.toContain('Commit: C5\n'); + expect(commandMsg).toContain('Commit: C6\n'); + }); + }); + + it('multiple included revisions', function() { + return runCommand(SETUP + 'git log right left', function(commandMsg) { + expect(commandMsg).toContain('Commit: C0\n'); + expect(commandMsg).toContain('Commit: C1\n'); + expect(commandMsg).toContain('Commit: C2\n'); + expect(commandMsg).toContain('Commit: C3\n'); + expect(commandMsg).toContain('Commit: C4\n'); + expect(commandMsg).toContain('Commit: C5\n'); + expect(commandMsg).not.toContain('Commit: C6\n'); + }); + }); + + it('multiple excluded revisions', function() { + return runCommand(SETUP + 'git log all ^right ^left', function(commandMsg) { + expect(commandMsg).not.toContain('Commit: C0\n'); + expect(commandMsg).not.toContain('Commit: C1\n'); + expect(commandMsg).not.toContain('Commit: C2\n'); + expect(commandMsg).not.toContain('Commit: C3\n'); + expect(commandMsg).not.toContain('Commit: C4\n'); + expect(commandMsg).not.toContain('Commit: C5\n'); + expect(commandMsg).toContain('Commit: C6\n'); + }); + }); + }); +}); diff --git a/__tests__/levels.spec.js b/__tests__/levels.spec.js index 8ee2e6fb..ee4bc5ab 100644 --- a/__tests__/levels.spec.js +++ b/__tests__/levels.spec.js @@ -1,16 +1,14 @@ var base = require('./base'); describe('GitEngine Levels', function() { - it('solves levels', function() { - var sequences = require('../src/levels/index').levelSequences; - Object.keys(sequences).forEach(function(sequenceKey) { - var levels = sequences[sequenceKey]; - Object.keys(levels).forEach(function(index) { - var levelBlob = levels[index]; - console.log('testing level', levelBlob.name.en_US); + var sequences = require('../src/levels/index').levelSequences; + Object.keys(sequences).forEach(function(sequenceKey) { + var levels = sequences[sequenceKey]; + Object.keys(levels).forEach(function(index) { + var levelBlob = levels[index]; + it('solves level ' + levelBlob['name']['en_US'] + ' in sequence ' + sequenceKey, function() { base.expectLevelSolved(levelBlob); - }.bind(this)); - }); + }); + }.bind(this)); }); }); - diff --git a/__tests__/mercurial.spec.js b/__tests__/mercurial.spec.js index d2f7eb4c..16b2e96e 100644 --- a/__tests__/mercurial.spec.js +++ b/__tests__/mercurial.spec.js @@ -4,7 +4,7 @@ var expectTreeAsync = base.expectTreeAsync; describe('Mercurial', function() { var assert = function(msg, command, tree) { it(msg, function() { - expectTreeAsync(command, tree); + return expectTreeAsync(command, tree); }); }; @@ -63,4 +63,3 @@ describe('Mercurial', function() { ); }); - diff --git a/__tests__/remote.spec.js b/__tests__/remote.spec.js index 9f5f51e6..96092f8a 100644 --- a/__tests__/remote.spec.js +++ b/__tests__/remote.spec.js @@ -3,280 +3,280 @@ var expectTreeAsync = base.expectTreeAsync; describe('Git Remotes', function() { it('clones', function() { - expectTreeAsync( + return expectTreeAsync( 'git clone', '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('does fake teamwork', function() { - expectTreeAsync( + return expectTreeAsync( 'git clone; git fakeTeamwork', '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('does fake teamwork and then fetches', function() { - expectTreeAsync( + return expectTreeAsync( 'git clone; git fakeTeamwork; git fetch', '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C2","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('pulls', function() { - expectTreeAsync( + return expectTreeAsync( 'git clone; git commit; git fakeTeamwork; git pull', '{"branches":{"master":{"target":"C4","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C3","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C1"],"id":"C3"},"C4":{"parents":["C2","C3"],"id":"C4"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C3","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C3":{"parents":["C1"],"id":"C3"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('pulls with rebase', function() { - expectTreeAsync( + return expectTreeAsync( 'git clone; git commit; git fakeTeamwork; git pull --rebase', '%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C2%27%22%2C%22id%22%3A%22master%22%2C%22remoteTrackingBranchID%22%3A%22o/master%22%2C%22localBranchesThatTrackThis%22%3Anull%7D%2C%22o/master%22%3A%7B%22target%22%3A%22C3%22%2C%22id%22%3A%22o/master%22%2C%22remoteTrackingBranchID%22%3Anull%2C%22localBranchesThatTrackThis%22%3A%5B%22master%22%5D%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C2%27%22%3A%7B%22parents%22%3A%5B%22C3%22%5D%2C%22id%22%3A%22C2%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%2C%22originTree%22%3A%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C3%22%2C%22id%22%3A%22master%22%2C%22remoteTrackingBranchID%22%3Anull%2C%22localBranchesThatTrackThis%22%3Anull%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C3%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%7D%7D' ); }); it('pushes', function() { - expectTreeAsync( + return expectTreeAsync( 'git clone; git commit; git push', '{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C2","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('pulls and then pushes', function() { - expectTreeAsync( + return expectTreeAsync( 'git clone; git commit; git fakeTeamwork; git pull; git push', '{"branches":{"master":{"target":"C4","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C4","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C1"],"id":"C3"},"C4":{"parents":["C2","C3"],"id":"C4"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C4","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C3":{"parents":["C1"],"id":"C3"},"C2":{"parents":["C1"],"id":"C2"},"C4":{"parents":["C2","C3"],"id":"C4"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('pulls with rebase and then pushes', function() { - expectTreeAsync( + return expectTreeAsync( 'git clone; git commit; git fakeTeamwork; git pull --rebase; git push', '%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C2%27%22%2C%22id%22%3A%22master%22%2C%22remoteTrackingBranchID%22%3A%22o/master%22%2C%22localBranchesThatTrackThis%22%3Anull%7D%2C%22o/master%22%3A%7B%22target%22%3A%22C2%27%22%2C%22id%22%3A%22o/master%22%2C%22remoteTrackingBranchID%22%3Anull%2C%22localBranchesThatTrackThis%22%3A%5B%22master%22%5D%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C2%27%22%3A%7B%22parents%22%3A%5B%22C3%22%5D%2C%22id%22%3A%22C2%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%2C%22originTree%22%3A%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C2%27%22%2C%22id%22%3A%22master%22%2C%22remoteTrackingBranchID%22%3Anull%2C%22localBranchesThatTrackThis%22%3Anull%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C2%27%22%3A%7B%22parents%22%3A%5B%22C3%22%5D%2C%22id%22%3A%22C2%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%7D%7D' ); }); it('clones with many branches', function() { - expectTreeAsync( + return expectTreeAsync( 'git branch bugFix; git clone', '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"bugFix":{"target":"C1","id":"bugFix","remoteTrackingBranchID":"o/bugFix"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null},"o/bugFix":{"target":"C1","id":"o/bugFix","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null},"bugFix":{"target":"C1","id":"bugFix","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('clones with a merge commit, does teamwork, fetches', function() { - expectTreeAsync( + return expectTreeAsync( 'git branch bugFix; git commit; git checkout bugFix; git commit; git merge master; git clone; git fakeTeamwork bugFix 2', '{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":"o/master"},"bugFix":{"target":"C4","id":"bugFix","remoteTrackingBranchID":"o/bugFix"},"o/master":{"target":"C2","id":"o/master","remoteTrackingBranchID":null},"o/bugFix":{"target":"C4","id":"o/bugFix","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C1"],"id":"C3"},"C4":{"parents":["C2","C3"],"id":"C4"}},"HEAD":{"target":"bugFix","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":null},"bugFix":{"target":"C6","id":"bugFix","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C1"],"id":"C3"},"C4":{"parents":["C2","C3"],"id":"C4"},"C5":{"parents":["C4"],"id":"C5"},"C6":{"parents":["C5"],"id":"C6"}},"HEAD":{"target":"bugFix","id":"HEAD"}}}' ); }); it('only fetches one branch if specified', function() { - expectTreeAsync( + return expectTreeAsync( 'git branch bugFix; git clone; git fakeTeamwork bugFix; git fakeTeamwork; git fetch origin bugFix', '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"bugFix":{"target":"C1","id":"bugFix","remoteTrackingBranchID":"o/bugFix"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null},"o/bugFix":{"target":"C2","id":"o/bugFix","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C3","id":"master","remoteTrackingBranchID":null},"bugFix":{"target":"C2","id":"bugFix","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C1"],"id":"C3"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('checks all branches for fetching', function() { - expectTreeAsync( + return expectTreeAsync( 'git branch bugFix; git clone; git fakeTeamwork; git fetch', '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"bugFix":{"target":"C1","id":"bugFix","remoteTrackingBranchID":"o/bugFix"},"o/master":{"target":"C2","id":"o/master","remoteTrackingBranchID":null},"o/bugFix":{"target":"C1","id":"o/bugFix","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":null},"bugFix":{"target":"C1","id":"bugFix","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('pulls with nothing and then commits', function() { - expectTreeAsync( + return expectTreeAsync( 'git clone; git pull; git commit', '{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('pulls from different remote tracking branches nad merges', function() { - expectTreeAsync( + return expectTreeAsync( 'git branch side; git clone; git fakeTeamwork side;git commit; git pull origin side;git pull;git fakeTeamwork master;git pull', '{"branches":{"master":{"target":"C6","id":"master","remoteTrackingBranchID":"o/master"},"side":{"target":"C1","id":"side","remoteTrackingBranchID":"o/side"},"o/master":{"target":"C5","id":"o/master","remoteTrackingBranchID":null},"o/side":{"target":"C2","id":"o/side","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C3":{"parents":["C1"],"id":"C3"},"C2":{"parents":["C1"],"id":"C2"},"C4":{"parents":["C2","C3"],"id":"C4"},"C5":{"parents":["C1"],"id":"C5"},"C6":{"parents":["C4","C5"],"id":"C6"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C5","id":"master","remoteTrackingBranchID":null},"side":{"target":"C2","id":"side","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C5":{"parents":["C1"],"id":"C5"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('pulls with rebase from different remote tracking', function() { - expectTreeAsync( + return expectTreeAsync( 'git branch side; git clone; git fakeTeamwork side;git commit; git pull origin side --rebase', '%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C3%27%22%2C%22id%22%3A%22master%22%2C%22remoteTrackingBranchID%22%3A%22o/master%22%7D%2C%22side%22%3A%7B%22target%22%3A%22C1%22%2C%22id%22%3A%22side%22%2C%22remoteTrackingBranchID%22%3A%22o/side%22%7D%2C%22o/master%22%3A%7B%22target%22%3A%22C1%22%2C%22id%22%3A%22o/master%22%2C%22remoteTrackingBranchID%22%3Anull%2C%22localBranchesThatTrackThis%22%3A%5B%22master%22%5D%7D%2C%22o/side%22%3A%7B%22target%22%3A%22C2%22%2C%22id%22%3A%22o/side%22%2C%22remoteTrackingBranchID%22%3Anull%2C%22localBranchesThatTrackThis%22%3A%5B%22side%22%5D%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%2C%22originTree%22%3A%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C1%22%2C%22id%22%3A%22master%22%2C%22remoteTrackingBranchID%22%3Anull%2C%22localBranchesThatTrackThis%22%3Anull%7D%2C%22side%22%3A%7B%22target%22%3A%22C2%22%2C%22id%22%3A%22side%22%2C%22remoteTrackingBranchID%22%3Anull%2C%22localBranchesThatTrackThis%22%3Anull%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22side%22%2C%22id%22%3A%22HEAD%22%7D%7D%7D' ); }); it('pushes to another remote', function() { - expectTreeAsync( + return expectTreeAsync( 'git branch side; git clone;git commit; git push origin HEAD:side', '{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":"o/master"},"side":{"target":"C1","id":"side","remoteTrackingBranchID":"o/side"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null},"o/side":{"target":"C2","id":"o/side","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null},"side":{"target":"C2","id":"side","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('pushes to tracking remote', function() { - expectTreeAsync( + return expectTreeAsync( 'git branch side; git clone;git commit;git push; go side; git commit; git push', '{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":"o/master"},"side":{"target":"C3","id":"side","remoteTrackingBranchID":"o/side"},"o/master":{"target":"C2","id":"o/master","remoteTrackingBranchID":null},"o/side":{"target":"C3","id":"o/side","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C1"],"id":"C3"}},"HEAD":{"target":"side","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":null},"side":{"target":"C3","id":"side","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C1"],"id":"C3"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('sets tracking when checking out remote branch', function() { - expectTreeAsync( + return expectTreeAsync( 'git clone; git checkout -b side o/master;git fakeTeamwork;git pull', '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C2","id":"o/master","remoteTrackingBranchID":null,"localBranchesThatTrackThis":["master","side"]},"side":{"target":"C2","id":"side","remoteTrackingBranchID":"o/master"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"side","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('also sets tracking when just branching', function() { - expectTreeAsync( + return expectTreeAsync( 'git clone; gb side o/master', '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null,"localBranchesThatTrackThis":["master","side"]},"side":{"target":"C1","id":"side","remoteTrackingBranchID":"o/master"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('can push with colon refspec', function() { - expectTreeAsync( + return expectTreeAsync( 'git clone; gc; git checkout -b foo HEAD~1; git push origin master:master', '{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C2","id":"o/master","remoteTrackingBranchID":null},"foo":{"target":"C1","id":"foo","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"foo","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('can delete branches with colon refspec', function() { - expectTreeAsync( + return expectTreeAsync( 'git branch foo; git clone; git push origin :foo', '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"foo":{"target":"C1","id":"foo","remoteTrackingBranchID":null},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('pushes new branch onto server', function() { - expectTreeAsync( + return expectTreeAsync( 'git clone; git commit; git push origin master:foo', '{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null},"o/foo":{"target":"C2","id":"o/foo","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null},"foo":{"target":"C2","id":"foo","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('does not push for HEAD', function() { - expectTreeAsync( + return expectTreeAsync( 'git clone; git commit; git checkout C2; git push', '{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"C2","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('does push for HEAD as a source though to a new branch', function() { - expectTreeAsync( + return expectTreeAsync( 'git clone; git commit; git checkout C2; git push origin HEAD:foo', '{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null},"o/foo":{"target":"C2","id":"o/foo","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"C2","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null},"foo":{"target":"C2","id":"foo","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('but it cant delete master on remote', function() { - expectTreeAsync( + return expectTreeAsync( 'git branch foo; git clone; git push origin :master', '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"foo":{"target":"C1","id":"foo","remoteTrackingBranchID":"o/foo"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null},"o/foo":{"target":"C1","id":"o/foo","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null},"foo":{"target":"C1","id":"foo","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('will prune the origin tree when deleting branches', function() { - expectTreeAsync( + return expectTreeAsync( 'git checkout -b foo; git commit; git clone; git push origin :foo', '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"foo":{"target":"C2","id":"foo","remoteTrackingBranchID":null},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"foo","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('will not push to a remote if the local ref does not exist', function() { - expectTreeAsync( + return expectTreeAsync( 'git clone; git push origin foo', '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('will push to the remote branch IF IT has tracking', function() { - expectTreeAsync( + return expectTreeAsync( 'git clone; git checkout -b foo o/master; git commit; git push', '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C2","id":"o/master","remoteTrackingBranchID":null},"foo":{"target":"C2","id":"foo","remoteTrackingBranchID":"o/master"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"foo","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('will push to a new remote branch if no tracking is set up', function() { - expectTreeAsync( + return expectTreeAsync( 'git clone; git checkout -b foo; git commit; git push', '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null},"foo":{"target":"C2","id":"foo","remoteTrackingBranchID":"o/foo"},"o/foo":{"target":"C2","id":"o/foo","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"foo","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null},"foo":{"target":"C2","id":"foo","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('will push to the remote tracking branch WHILE NOT on branch if it is set up', function() { - expectTreeAsync( + return expectTreeAsync( 'git clone; git checkout -b foo o/master; git commit; go master; git push origin foo', '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C2","id":"o/master","remoteTrackingBranchID":null},"foo":{"target":"C2","id":"foo","remoteTrackingBranchID":"o/master"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('will not fetch if ref does not exist on remote', function() { - expectTreeAsync( + return expectTreeAsync( 'git clone; git fakeTeamwork; git fetch foo:master', '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('does not fetch if ref does not exist on remote with one arg', function() { - expectTreeAsync( + return expectTreeAsync( 'git clone; git fakeTeamwork; git fetch foo', '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('validates branch names when fetching', function() { - expectTreeAsync( + return expectTreeAsync( 'git clone; git fakeTeamwork; git fetch master:HEAD; git fetch master:f<>', '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('fetches only one remote if specified', function() { - expectTreeAsync( + return expectTreeAsync( 'git clone;gc;git push origin master:banana;git fakeTeamwork banana;git fakeTeamwork master;git fetch origin banana', '{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null},"o/banana":{"target":"C3","id":"o/banana","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C2"],"id":"C3"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C4","id":"master","remoteTrackingBranchID":null},"banana":{"target":"C3","id":"banana","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C2"],"id":"C3"},"C4":{"parents":["C1"],"id":"C4"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('sets remote tracking', function() { - expectTreeAsync( + return expectTreeAsync( 'git clone; git branch foo; git branch -u o/master foo', '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null},"foo":{"target":"C1","id":"foo","remoteTrackingBranchID":"o/master"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('sets remote tracking on current branch if not specified', function() { - expectTreeAsync( + return expectTreeAsync( 'git clone; git checkout -b foo; git branch -u o/master', '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null},"foo":{"target":"C1","id":"foo","remoteTrackingBranchID":"o/master"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"foo","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('fetches with no args, explicit dest args, and with just one arg', function() { - expectTreeAsync( + return expectTreeAsync( 'git clone; git fakeTeamwork; git fetch origin master:o/master;git fakeTeamwork;git fetch;git fakeTeamwork;git fetch origin master', '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C4","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C2"],"id":"C3"},"C4":{"parents":["C3"],"id":"C4"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C4","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C2"],"id":"C3"},"C4":{"parents":["C3"],"id":"C4"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); - it('doesnt fetch if out of sync, but will update explicit dest if specified', function() { - expectTreeAsync( + it('doesn\'t fetch if out of sync, but will update explicit dest if specified', function() { + return expectTreeAsync( 'git clone; git fakeTeamwork; go HEAD~1; git fetch origin master:master;go master; gc; go HEAD~1; git fakeTeamwork;git fetch origin master:master', '{"branches":{"master":{"target":"C3","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C2"],"id":"C3"}},"HEAD":{"target":"C2","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C4","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C4":{"parents":["C2"],"id":"C4"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('pulls to the right branch and destination', function() { - expectTreeAsync( + return expectTreeAsync( 'git clone; git checkout -b side o/master;git fakeTeamwork;git pull origin master:o/master', '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C2","id":"o/master","remoteTrackingBranchID":null},"side":{"target":"C2","id":"side","remoteTrackingBranchID":"o/master"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"side","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); it('correctly checks upstream when pushing to a remote where commits already exist but branch is not updated DAYAM dawg', function() { - expectTreeAsync( + return expectTreeAsync( 'git push origin master^:master', '{"branches":{"master":{"target":"C9","id":"master","remoteTrackingBranchID":"o/master"},"foo":{"target":"C8","id":"foo","remoteTrackingBranchID":"o/foo"},"o/master":{"target":"C5","id":"o/master","remoteTrackingBranchID":null},"o/foo":{"target":"C5","id":"o/foo","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C2"],"id":"C3"},"C4":{"parents":["C1"],"id":"C4"},"C5":{"parents":["C2","C4"],"id":"C5"},"C6":{"parents":["C4"],"id":"C6"},"C7":{"parents":["C6"],"id":"C7"},"C8":{"parents":["C5","C7"],"id":"C8"},"C9":{"parents":["C5"],"id":"C9"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C5","id":"master","remoteTrackingBranchID":null},"foo":{"target":"C5","id":"foo","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C4":{"parents":["C1"],"id":"C4"},"C5":{"parents":["C2","C4"],"id":"C5"}},"HEAD":{"target":"master","id":"HEAD"}}}', '{"branches":{"master":{"target":"C9","id":"master","remoteTrackingBranchID":"o/master"},"foo":{"target":"C8","id":"foo","remoteTrackingBranchID":"o/foo"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null},"o/foo":{"target":"C5","id":"o/foo","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C2"],"id":"C3"},"C4":{"parents":["C1"],"id":"C4"},"C5":{"parents":["C2","C4"],"id":"C5"},"C6":{"parents":["C4"],"id":"C6"},"C7":{"parents":["C6"],"id":"C7"},"C8":{"parents":["C5","C7"],"id":"C8"},"C9":{"parents":["C5"],"id":"C9"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null},"foo":{"target":"C5","id":"foo","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C4":{"parents":["C1"],"id":"C4"},"C5":{"parents":["C2","C4"],"id":"C5"}},"HEAD":{"target":"master","id":"HEAD"}}}' @@ -284,130 +284,130 @@ describe('Git Remotes', function() { }); it('correctly resolves source during git fetch with params', function() { - expectTreeAsync( + return expectTreeAsync( 'git clone; git push origin master:foo; git fakeTeamwork foo 2; git fetch origin foo^:blah', '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null},"o/foo":{"target":"C1","id":"o/foo","remoteTrackingBranchID":null},"blah":{"target":"C2","id":"blah","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null},"foo":{"target":"C3","id":"foo","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C2"],"id":"C3"}},"HEAD":{"target":"foo","id":"HEAD"}}}' ); }); it('correctly makes a new branch during fetch despite nothing to download', function() { - expectTreeAsync( + return expectTreeAsync( 'git clone; git push origin master:foo', '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null},"o/foo":{"target":"C1","id":"o/foo","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null},"foo":{"target":"C1","id":"foo","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); }); - it('correctly resolves existing commits and updates', function() { - expectTreeAsync( + it('correctly resolves existing commits and updates', function() { + return expectTreeAsync( 'git clone; git push origin master:foo; git fakeTeamwork foo 2; git fetch origin foo^:blah;go C0; git fetch origin foo^:master', '{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null},"o/foo":{"target":"C1","id":"o/foo","remoteTrackingBranchID":null},"blah":{"target":"C2","id":"blah","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"C0","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null},"foo":{"target":"C3","id":"foo","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C2"],"id":"C3"}},"HEAD":{"target":"foo","id":"HEAD"}}}' ); - }); + }); - it('doesnt let you fetch to master if you are checked out there', function() { - expectTreeAsync( - 'git clone; git push origin master:foo; git fakeTeamwork foo 2; git fetch origin foo^:blah; git fetch foo:master', - '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null},"o/foo":{"target":"C1","id":"o/foo","remoteTrackingBranchID":null},"blah":{"target":"C2","id":"blah","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null},"foo":{"target":"C3","id":"foo","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C2"],"id":"C3"}},"HEAD":{"target":"foo","id":"HEAD"}}}' - ); - }); + it('doesn\'t let you fetch to master if you are checked out there', function() { + return expectTreeAsync( + 'git clone; git push origin master:foo; git fakeTeamwork foo 2; git fetch origin foo^:blah; git fetch foo:master', + '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null},"o/foo":{"target":"C1","id":"o/foo","remoteTrackingBranchID":null},"blah":{"target":"C2","id":"blah","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null},"foo":{"target":"C3","id":"foo","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C2"],"id":"C3"}},"HEAD":{"target":"foo","id":"HEAD"}}}' + ); + }); - it('doesnt let you delete branches that dont exist', function() { - expectTreeAsync( - 'git clone; git push origin :foo', - '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"}}}' - ); - }); + it('doesn\'t let you delete branches that don\'t exist', function() { + return expectTreeAsync( + 'git clone; git push origin :foo', + '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"}}}' + ); + }); - it('pulls to a new branch and then merges in that branch', function() { - expectTreeAsync( - 'git clone; git fakeTeamwork; git commit; git pull origin master:bar', - '{"branches":{"master":{"target":"C4","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null},"bar":{"target":"C2","id":"bar","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C3":{"parents":["C1"],"id":"C3"},"C2":{"parents":["C1"],"id":"C2"},"C4":{"parents":["C2","C3"],"id":"C4"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"}}}' - ); - }); + it('pulls to a new branch and then merges in that branch', function() { + return expectTreeAsync( + 'git clone; git fakeTeamwork; git commit; git pull origin master:bar', + '{"branches":{"master":{"target":"C4","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null},"bar":{"target":"C2","id":"bar","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C3":{"parents":["C1"],"id":"C3"},"C2":{"parents":["C1"],"id":"C2"},"C4":{"parents":["C2","C3"],"id":"C4"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"}}}' + ); + }); - it('makes a new branch from pull and doesnt bork', function() { - expectTreeAsync( - 'git clone; git pull origin :bar', - '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null},"bar":{"target":"C1","id":"bar","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"}}}' - ); - }); + it('makes a new branch from pull and doesn\'t bork', function() { + return expectTreeAsync( + 'git clone; git pull origin :bar', + '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null},"bar":{"target":"C1","id":"bar","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"}}}' + ); + }); - it('makes the new branch on push in the right place', function() { - expectTreeAsync( - 'git clone; git fakeTeamwork; git push origin master:foo', - '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null},"o/foo":{"target":"C1","id":"o/foo","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":null},"foo":{"target":"C1","id":"foo","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"}}}' - ); - }); + it('makes the new branch on push in the right place', function() { + return expectTreeAsync( + 'git clone; git fakeTeamwork; git push origin master:foo', + '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null},"o/foo":{"target":"C1","id":"o/foo","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":null},"foo":{"target":"C1","id":"foo","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"}}}' + ); + }); - it('tracks remote with -u', function() { - expectTreeAsync( - 'git clone; git branch foo; git branch -u o/master foo', - '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null},"foo":{"target":"C1","id":"foo","remoteTrackingBranchID":"o/master"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"}}}' - ); - }); + it('tracks remote with -u', function() { + return expectTreeAsync( + 'git clone; git branch foo; git branch -u o/master foo', + '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null},"foo":{"target":"C1","id":"foo","remoteTrackingBranchID":"o/master"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"}}}' + ); + }); - it('does not fetch if one arg is not branch ref', function() { - expectTreeAsync( - 'git clone; git fakeTeamwork 2; git fetch origin master~1', - '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C3","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C2"],"id":"C3"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"}}}' - ); - }); + it('does not fetch if one arg is not branch ref', function() { + return expectTreeAsync( + 'git clone; git fakeTeamwork 2; git fetch origin master~1', + '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C3","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C2"],"id":"C3"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"}}}' + ); + }); - it('creates the branch on the fly', function() { - expectTreeAsync( - 'git clone; git commit; go -b side; git push origin side', - '{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null},"side":{"target":"C2","id":"side","remoteTrackingBranchID":"o/side"},"o/side":{"target":"C2","id":"o/side","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"tags":{},"HEAD":{"target":"side","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null},"side":{"target":"C2","id":"side","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"}}}' - ); - }); + it('creates the branch on the fly', function() { + return expectTreeAsync( + 'git clone; git commit; go -b side; git push origin side', + '{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null},"side":{"target":"C2","id":"side","remoteTrackingBranchID":"o/side"},"o/side":{"target":"C2","id":"o/side","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"tags":{},"HEAD":{"target":"side","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null},"side":{"target":"C2","id":"side","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"}}}' + ); + }); - it('does not create the o/master branch on remote', function() { - expectTreeAsync( - 'git clone; git commit; git push origin o/master', - '{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"}}}' - ); - }); + it('does not create the o/master branch on remote', function() { + return expectTreeAsync( + 'git clone; git commit; git push origin o/master', + '{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"}}}' + ); + }); - it('pulls with rebase correctly in weird situation with no rebase to do', function() { - expectTreeAsync( - 'git checkout -b side; git commit; git checkout master; git commit; git commit; git merge side; git commit; git clone; git checkout -b main master^^^; git rebase side; git rebase main master; git push;git pull --rebase', - '%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C6%22%2C%22id%22%3A%22master%22%2C%22remoteTrackingBranchID%22%3A%22o/master%22%7D%2C%22side%22%3A%7B%22target%22%3A%22C2%22%2C%22id%22%3A%22side%22%2C%22remoteTrackingBranchID%22%3A%22o/side%22%7D%2C%22o/master%22%3A%7B%22target%22%3A%22C6%22%2C%22id%22%3A%22o/master%22%2C%22remoteTrackingBranchID%22%3Anull%7D%2C%22o/side%22%3A%7B%22target%22%3A%22C2%22%2C%22id%22%3A%22o/side%22%2C%22remoteTrackingBranchID%22%3Anull%7D%2C%22main%22%3A%7B%22target%22%3A%22C3%27%22%2C%22id%22%3A%22main%22%2C%22remoteTrackingBranchID%22%3Anull%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C4%22%3A%7B%22parents%22%3A%5B%22C3%22%5D%2C%22id%22%3A%22C4%22%7D%2C%22C5%22%3A%7B%22parents%22%3A%5B%22C2%22%2C%22C4%22%5D%2C%22id%22%3A%22C5%22%7D%2C%22C6%22%3A%7B%22parents%22%3A%5B%22C5%22%5D%2C%22id%22%3A%22C6%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%27%22%7D%2C%22C4%27%22%3A%7B%22parents%22%3A%5B%22C3%27%22%5D%2C%22id%22%3A%22C4%27%22%7D%2C%22C6%27%22%3A%7B%22parents%22%3A%5B%22C4%27%22%5D%2C%22id%22%3A%22C6%27%22%7D%7D%2C%22tags%22%3A%7B%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%2C%22originTree%22%3A%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C6%22%2C%22id%22%3A%22master%22%2C%22remoteTrackingBranchID%22%3Anull%7D%2C%22side%22%3A%7B%22target%22%3A%22C2%22%2C%22id%22%3A%22side%22%2C%22remoteTrackingBranchID%22%3Anull%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C4%22%3A%7B%22parents%22%3A%5B%22C3%22%5D%2C%22id%22%3A%22C4%22%7D%2C%22C5%22%3A%7B%22parents%22%3A%5B%22C2%22%2C%22C4%22%5D%2C%22id%22%3A%22C5%22%7D%2C%22C6%22%3A%7B%22parents%22%3A%5B%22C5%22%5D%2C%22id%22%3A%22C6%22%7D%7D%2C%22tags%22%3A%7B%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%7D%7D' - ); - }); + it('pulls with rebase correctly in weird situation with no rebase to do', function() { + return expectTreeAsync( + 'git checkout -b side; git commit; git checkout master; git commit; git commit; git merge side; git commit; git clone; git checkout -b otherMain master^^^; git rebase side; git rebase otherMain master; git push;git pull --rebase', + '%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C6%22%2C%22id%22%3A%22master%22%2C%22remoteTrackingBranchID%22%3A%22o/master%22%7D%2C%22side%22%3A%7B%22target%22%3A%22C2%22%2C%22id%22%3A%22side%22%2C%22remoteTrackingBranchID%22%3A%22o/side%22%7D%2C%22o/master%22%3A%7B%22target%22%3A%22C6%22%2C%22id%22%3A%22o/master%22%2C%22remoteTrackingBranchID%22%3Anull%7D%2C%22o/side%22%3A%7B%22target%22%3A%22C2%22%2C%22id%22%3A%22o/side%22%2C%22remoteTrackingBranchID%22%3Anull%7D%2C%22otherMain%22%3A%7B%22target%22%3A%22C3%27%22%2C%22id%22%3A%22otherMain%22%2C%22remoteTrackingBranchID%22%3Anull%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C4%22%3A%7B%22parents%22%3A%5B%22C3%22%5D%2C%22id%22%3A%22C4%22%7D%2C%22C5%22%3A%7B%22parents%22%3A%5B%22C2%22%2C%22C4%22%5D%2C%22id%22%3A%22C5%22%7D%2C%22C6%22%3A%7B%22parents%22%3A%5B%22C5%22%5D%2C%22id%22%3A%22C6%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%27%22%7D%2C%22C4%27%22%3A%7B%22parents%22%3A%5B%22C3%27%22%5D%2C%22id%22%3A%22C4%27%22%7D%2C%22C6%27%22%3A%7B%22parents%22%3A%5B%22C4%27%22%5D%2C%22id%22%3A%22C6%27%22%7D%7D%2C%22tags%22%3A%7B%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%2C%22originTree%22%3A%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C6%22%2C%22id%22%3A%22master%22%2C%22remoteTrackingBranchID%22%3Anull%7D%2C%22side%22%3A%7B%22target%22%3A%22C2%22%2C%22id%22%3A%22side%22%2C%22remoteTrackingBranchID%22%3Anull%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C4%22%3A%7B%22parents%22%3A%5B%22C3%22%5D%2C%22id%22%3A%22C4%22%7D%2C%22C5%22%3A%7B%22parents%22%3A%5B%22C2%22%2C%22C4%22%5D%2C%22id%22%3A%22C5%22%7D%2C%22C6%22%3A%7B%22parents%22%3A%5B%22C5%22%5D%2C%22id%22%3A%22C6%22%7D%7D%2C%22tags%22%3A%7B%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%7D%7D' + ); + }); - it('pulls with rebase in other weird situation with just fast forward', function() { - expectTreeAsync( - 'git clone; git fakeTeamwork; git pull --rebase', + it('pulls with rebase in other weird situation with just fast forward', function() { + return expectTreeAsync( + 'git clone; git fakeTeamwork; git pull --rebase', '{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C2","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"}}}' - ); - }); + ); + }); /* TODO -- enable this back when we have better async tree compare, it takes too long right now - it('will correctly resolve the dependency order of commits when fetching or pushing', function() { - expectTreeAsync( - 'git clone; git commit; git commit; git commit; git checkout -b test C2; git commit; git checkout master; git push; git checkout master; git merge test; git commit; git push; git checkout test; git commit; git commit; git checkout -b feat1 master; git commit; git merge test; git checkout master; git merge test; git checkout feat1; git commit; git checkout master; git merge feat1; git push', - '{"branches":{"master":{"target":"C14","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C7","id":"o/master","remoteTrackingBranchID":null},"test":{"target":"C9","id":"test","remoteTrackingBranchID":null},"feat1":{"target":"C13","id":"feat1","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C2"],"id":"C3"},"C4":{"parents":["C3"],"id":"C4"},"C5":{"parents":["C2"],"id":"C5"},"C6":{"parents":["C4","C5"],"id":"C6"},"C7":{"parents":["C6"],"id":"C7"},"C8":{"parents":["C5"],"id":"C8"},"C9":{"parents":["C8"],"id":"C9"},"C10":{"parents":["C7"],"id":"C10"},"C11":{"parents":["C10","C9"],"id":"C11"},"C12":{"parents":["C7","C9"],"id":"C12"},"C13":{"parents":["C11"],"id":"C13"},"C14":{"parents":["C12","C13"],"id":"C14"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C7","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C2"],"id":"C3"},"C4":{"parents":["C3"],"id":"C4"},"C5":{"parents":["C2"],"id":"C5"},"C6":{"parents":["C4","C5"],"id":"C6"},"C7":{"parents":["C6"],"id":"C7"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"}}}' - ); + it('will correctly resolve the dependency order of commits when fetching or pushing', function() { + return expectTreeAsync( + 'git clone; git commit; git commit; git commit; git checkout -b test C2; git commit; git checkout master; git push; git checkout master; git merge test; git commit; git push; git checkout test; git commit; git commit; git checkout -b feat1 master; git commit; git merge test; git checkout master; git merge test; git checkout feat1; git commit; git checkout master; git merge feat1; git push', + '{"branches":{"master":{"target":"C14","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C7","id":"o/master","remoteTrackingBranchID":null},"test":{"target":"C9","id":"test","remoteTrackingBranchID":null},"feat1":{"target":"C13","id":"feat1","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C2"],"id":"C3"},"C4":{"parents":["C3"],"id":"C4"},"C5":{"parents":["C2"],"id":"C5"},"C6":{"parents":["C4","C5"],"id":"C6"},"C7":{"parents":["C6"],"id":"C7"},"C8":{"parents":["C5"],"id":"C8"},"C9":{"parents":["C8"],"id":"C9"},"C10":{"parents":["C7"],"id":"C10"},"C11":{"parents":["C10","C9"],"id":"C11"},"C12":{"parents":["C7","C9"],"id":"C12"},"C13":{"parents":["C11"],"id":"C13"},"C14":{"parents":["C12","C13"],"id":"C14"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C7","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C2"],"id":"C3"},"C4":{"parents":["C3"],"id":"C4"},"C5":{"parents":["C2"],"id":"C5"},"C6":{"parents":["C4","C5"],"id":"C6"},"C7":{"parents":["C6"],"id":"C7"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"}}}' + ); });*/ - it('uses git force to bypass upstream check', function() { - expectTreeAsync( - 'git clone; git commit; git push; go C1; git branch -f master C1; go master; git commit; git commit; go C1; git checkout -b side; git commit; go master; git merge side; git push --force', - '{"branches":{"master":{"target":"C6","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C6","id":"o/master","remoteTrackingBranchID":null},"side":{"target":"C5","id":"side","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C1"],"id":"C3"},"C4":{"parents":["C3"],"id":"C4"},"C5":{"parents":["C1"],"id":"C5"},"C6":{"parents":["C4","C5"],"id":"C6"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C6","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C5":{"parents":["C1"],"id":"C5"},"C3":{"parents":["C1"],"id":"C3"},"C4":{"parents":["C3"],"id":"C4"},"C6":{"parents":["C4","C5"],"id":"C6"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"}}}' - ); - }); + it('uses git force to bypass upstream check', function() { + return expectTreeAsync( + 'git clone; git commit; git push; go C1; git branch -f master C1; go master; git commit; git commit; go C1; git checkout -b side; git commit; go master; git merge side; git push --force', + '{"branches":{"master":{"target":"C6","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C6","id":"o/master","remoteTrackingBranchID":null},"side":{"target":"C5","id":"side","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C1"],"id":"C3"},"C4":{"parents":["C3"],"id":"C4"},"C5":{"parents":["C1"],"id":"C5"},"C6":{"parents":["C4","C5"],"id":"C6"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C6","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C5":{"parents":["C1"],"id":"C5"},"C3":{"parents":["C1"],"id":"C3"},"C4":{"parents":["C3"],"id":"C4"},"C6":{"parents":["C4","C5"],"id":"C6"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"}}}' + ); + }); it('uses --push to delete commits', function() { - expectTreeAsync( + return expectTreeAsync( 'git commit; git clone;git reset HEAD~1;git push --force', '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"}}}' - ); + ); }); it('uses --push to delete commits and can push again after', function() { - expectTreeAsync( + return expectTreeAsync( 'git commit; git clone;git reset HEAD~1;git push --force;git commit; git push ', '{"branches":{"master":{"target":"C3","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C3","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C1"],"id":"C3"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C3","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C1"],"id":"C3"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"}}}' - ); + ); }); diff --git a/__tests__/simpleRemote.spec.js b/__tests__/simpleRemote.spec.js index 247572b6..b93ed13e 100644 --- a/__tests__/simpleRemote.spec.js +++ b/__tests__/simpleRemote.spec.js @@ -3,7 +3,7 @@ var expectTreeAsync = base.expectTreeAsync; describe('Git Remote simple', function() { it('clones', function() { - expectTreeAsync( + return expectTreeAsync( 'git clone', '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"}}}' ); diff --git a/__tests__/treeCompare.spec.js b/__tests__/treeCompare.spec.js index 83efa368..ffa27466 100644 --- a/__tests__/treeCompare.spec.js +++ b/__tests__/treeCompare.spec.js @@ -49,9 +49,21 @@ describe('Tree Compare', function() { ); }); + it('compares with considering leftover branches', function() { + testMethod( + { + compareAllBranchesAndEnforceBranchCleanup: true, + }, + '{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":null},"foo":{"target":"C2","id":"foo","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"tags":{},"HEAD":{"target":"foo","id":"HEAD"}}', + { + '{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":null},"foo":{"target":"C2","id":"foo","remoteTrackingBranchID":null},"randoBran":{"target":"C2","id":"randoBran","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"tags":{},"HEAD":{"target":"foo","id":"HEAD"}}': false, + }, + ); + }); + it('deep compares on origin tree', function() { testMethod( - {}, // checked for all methods so this doesnt matter + {}, // checked for all methods so this doesn't matter // state with originTree '{"branches":{"master":{"target":"C1","id":"master"},"o/master":{"target":"C1","id":"o/master"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"remoteTrackingBranch":null,"remote":false,"target":"C1","id":"master","type":"branch"}},"commits":{"C0":{"type":"commit","parents":[],"author":"Peter Cottle","createTime":"Wed Jul 24 2013 09:58:50 GMT-0700 (PDT)","commitMessage":"Quick commit. Go Bears!","id":"C0","rootCommit":true},"C1":{"type":"commit","parents":["C0"],"author":"Peter Cottle","createTime":"Wed Jul 24 2013 09:58:50 GMT-0700 (PDT)","commitMessage":"Quick commit. Go Bears!","id":"C1"}},"HEAD":{"target":"master","id":"HEAD","type":"general ref"}}}', { @@ -173,5 +185,3 @@ describe('Tree Compare', function() { ); }); }); - - diff --git a/assets/emoji_table.rtf b/assets/emoji_table.rtf deleted file mode 100644 index 6704f314..00000000 --- a/assets/emoji_table.rtf +++ /dev/null @@ -1,2523 +0,0 @@ -{\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf210 -{\fonttbl\f0\fnil\fcharset0 AppleColorEmoji;\f1\fnil\fcharset0 Monaco;\f2\fnil\fcharset77 ZapfDingbatsITC; -\f3\fnil\fcharset128 HiraKakuProN-W3;\f4\fnil\fcharset0 LucidaGrande;\f5\fnil\fcharset0 AppleSymbols; -\f6\fnil\fcharset134 STHeitiSC-Light;\f7\fnil\fcharset129 AppleSDGothicNeo-Regular;} -{\colortbl;\red255\green255\blue255;} -\margl1440\margr1440\vieww18700\viewh19820\viewkind0 -\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural - -\f0\fs24 \cf0 \uc0\u55357 \u56833 -\f1 \\ud83d\\ude01 grinning face with smiling eyes\ - -\f0 \uc0\u55357 \u56834 -\f1 \\ud83d\\ude02 face with tears of joy\ - -\f0 \uc0\u55357 \u56835 -\f1 \\ud83d\\ude03 smiling face with open mouth\ - -\f0 \uc0\u55357 \u56836 -\f1 \\ud83d\\ude04 smiling face with open mouth and smiling eyes\ - -\f0 \uc0\u55357 \u56837 -\f1 \\ud83d\\ude05 smiling face with open mouth and cold sweat\ - -\f0 \uc0\u55357 \u56838 -\f1 \\ud83d\\ude06 smiling face with open mouth and tightly-closed eyes\ - -\f0 \uc0\u55357 \u56841 -\f1 \\ud83d\\ude09 winking face\ - -\f0 \uc0\u55357 \u56842 -\f1 \\ud83d\\ude0a smiling face with smiling eyes\ - -\f0 \uc0\u55357 \u56843 -\f1 \\ud83d\\ude0b face savouring delicious food\ - -\f0 \uc0\u55357 \u56844 -\f1 \\ud83d\\ude0c relieved face\ - -\f0 \uc0\u55357 \u56845 -\f1 \\ud83d\\ude0d smiling face with heart-shaped eyes\ - -\f0 \uc0\u55357 \u56847 -\f1 \\ud83d\\ude0f smirking face\ - -\f0 \uc0\u55357 \u56850 -\f1 \\ud83d\\ude12 unamused face\ - -\f0 \uc0\u55357 \u56851 -\f1 \\ud83d\\ude13 face with cold sweat\ - -\f0 \uc0\u55357 \u56852 -\f1 \\ud83d\\ude14 pensive face\ - -\f0 \uc0\u55357 \u56854 -\f1 \\ud83d\\ude16 confounded face\ - -\f0 \uc0\u55357 \u56856 -\f1 \\ud83d\\ude18 face throwing a kiss\ - -\f0 \uc0\u55357 \u56858 -\f1 \\ud83d\\ude1a kissing face with closed eyes\ - -\f0 \uc0\u55357 \u56860 -\f1 \\ud83d\\ude1c face with stuck-out tongue and winking eye\ - -\f0 \uc0\u55357 \u56861 -\f1 \\ud83d\\ude1d face with stuck-out tongue and tightly-closed eyes\ - -\f0 \uc0\u55357 \u56862 -\f1 \\ud83d\\ude1e disappointed face\ - -\f0 \uc0\u55357 \u56864 -\f1 \\ud83d\\ude20 angry face\ - -\f0 \uc0\u55357 \u56865 -\f1 \\ud83d\\ude21 pouting face\ - -\f0 \uc0\u55357 \u56866 -\f1 \\ud83d\\ude22 crying face\ - -\f0 \uc0\u55357 \u56867 -\f1 \\ud83d\\ude23 persevering face\ - -\f0 \uc0\u55357 \u56868 -\f1 \\ud83d\\ude24 face with look of triumph\ - -\f0 \uc0\u55357 \u56869 -\f1 \\ud83d\\ude25 disappointed but relieved face\ - -\f0 \uc0\u55357 \u56872 -\f1 \\ud83d\\ude28 fearful face\ - -\f0 \uc0\u55357 \u56873 -\f1 \\ud83d\\ude29 weary face\ - -\f0 \uc0\u55357 \u56874 -\f1 \\ud83d\\ude2a sleepy face\ - -\f0 \uc0\u55357 \u56875 -\f1 \\ud83d\\ude2b tired face\ - -\f0 \uc0\u55357 \u56877 -\f1 \\ud83d\\ude2d loudly crying face\ - -\f0 \uc0\u55357 \u56880 -\f1 \\ud83d\\ude30 face with open mouth and cold sweat\ - -\f0 \uc0\u55357 \u56881 -\f1 \\ud83d\\ude31 face screaming in fear\ - -\f0 \uc0\u55357 \u56882 -\f1 \\ud83d\\ude32 astonished face\ - -\f0 \uc0\u55357 \u56883 -\f1 \\ud83d\\ude33 flushed face\ - -\f0 \uc0\u55357 \u56885 -\f1 \\ud83d\\ude35 dizzy face\ - -\f0 \uc0\u55357 \u56887 -\f1 \\ud83d\\ude37 face with medical mask\ - -\f0 \uc0\u55357 \u56888 -\f1 \\ud83d\\ude38 grinning cat face with smiling eyes\ - -\f0 \uc0\u55357 \u56889 -\f1 \\ud83d\\ude39 cat face with tears of joy\ - -\f0 \uc0\u55357 \u56890 -\f1 \\ud83d\\ude3a smiling cat face with open mouth\ - -\f0 \uc0\u55357 \u56891 -\f1 \\ud83d\\ude3b smiling cat face with heart-shaped eyes\ - -\f0 \uc0\u55357 \u56892 -\f1 \\ud83d\\ude3c cat face with wry smile\ - -\f0 \uc0\u55357 \u56893 -\f1 \\ud83d\\ude3d kissing cat face with closed eyes\ - -\f0 \uc0\u55357 \u56894 -\f1 \\ud83d\\ude3e pouting cat face\ - -\f0 \uc0\u55357 \u56895 -\f1 \\ud83d\\ude3f crying cat face\ - -\f0 \uc0\u55357 \u56896 -\f1 \\ud83d\\ude40 weary cat face\ - -\f0 \uc0\u55357 \u56901 -\f1 \\ud83d\\ude45 face with no good gesture\ - -\f0 \uc0\u55357 \u56902 -\f1 \\ud83d\\ude46 face with ok gesture\ - -\f0 \uc0\u55357 \u56903 -\f1 \\ud83d\\ude47 person bowing deeply\ - -\f0 \uc0\u55357 \u56904 -\f1 \\ud83d\\ude48 see-no-evil monkey\ - -\f0 \uc0\u55357 \u56905 -\f1 \\ud83d\\ude49 hear-no-evil monkey\ - -\f0 \uc0\u55357 \u56906 -\f1 \\ud83d\\ude4a speak-no-evil monkey\ - -\f0 \uc0\u55357 \u56907 -\f1 \\ud83d\\ude4b happy person raising one hand\ - -\f0 \uc0\u55357 \u56908 -\f1 \\ud83d\\ude4c person raising both hands in celebration\ - -\f0 \uc0\u55357 \u56909 -\f1 \\ud83d\\ude4d person frowning\ - -\f0 \uc0\u55357 \u56910 -\f1 \\ud83d\\ude4e person with pouting face\ - -\f0 \uc0\u55357 \u56911 -\f1 \\ud83d\\ude4f person with folded hands\ - -\f2 \uc0\u9986 -\f1 \\u2702 black scissors\ - -\f0 \uc0\u9989 -\f1 \\u2705 white heavy check mark\ - -\f2 \uc0\u9992 -\f1 \\u2708 airplane\ - -\f2 \uc0\u9993 -\f1 \\u2709 envelope\ - -\f0 \uc0\u9994 -\f1 \\u270a raised fist\ - -\f0 \uc0\u9995 -\f1 \\u270b raised hand\ - -\f2 \uc0\u9996 -\f1 \\u270c victory hand\ - -\f2 \uc0\u9999 -\f1 \\u270f pencil\ - -\f2 \uc0\u10002 -\f1 \\u2712 black nib\ - -\f2 \uc0\u10004 -\f1 \\u2714 heavy check mark\ - -\f2 \uc0\u10006 -\f1 \\u2716 heavy multiplication x\ - -\f0 \uc0\u10024 -\f1 \\u2728 sparkles\ - -\f2 \uc0\u10035 -\f1 \\u2733 eight spoked asterisk\ - -\f2 \uc0\u10036 -\f1 \\u2734 eight pointed black star\ - -\f2 \uc0\u10052 -\f1 \\u2744 snowflake\ - -\f2 \uc0\u10055 -\f1 \\u2747 sparkle\ - -\f0 \uc0\u10060 -\f1 \\u274c cross mark\ - -\f0 \uc0\u10062 -\f1 \\u274e negative squared cross mark\ - -\f0 \uc0\u10067 -\f1 \\u2753 black question mark ornament\ - -\f0 \uc0\u10068 -\f1 \\u2754 white question mark ornament\ - -\f0 \uc0\u10069 -\f1 \\u2755 white exclamation mark ornament\ - -\f0 \uc0\u10071 -\f1 \\u2757 heavy exclamation mark symbol\ - -\f2 \uc0\u10084 -\f1 \\u2764 heavy black heart\ - -\f0 \uc0\u10133 -\f1 \\u2795 heavy plus sign\ - -\f0 \uc0\u10134 -\f1 \\u2796 heavy minus sign\ - -\f0 \uc0\u10135 -\f1 \\u2797 heavy division sign\ - -\f2 \uc0\u10145 -\f1 \\u27a1 black rightwards arrow\ - -\f0 \uc0\u10160 -\f1 \\u27b0 curly loop\ - -\f0 \uc0\u55357 \u56960 -\f1 \\ud83d\\ude80 rocket\ - -\f0 \uc0\u55357 \u56963 -\f1 \\ud83d\\ude83 railway car\ - -\f0 \uc0\u55357 \u56964 -\f1 \\ud83d\\ude84 high-speed train\ - -\f0 \uc0\u55357 \u56965 -\f1 \\ud83d\\ude85 high-speed train with bullet nose\ - -\f0 \uc0\u55357 \u56967 -\f1 \\ud83d\\ude87 metro\ - -\f0 \uc0\u55357 \u56969 -\f1 \\ud83d\\ude89 station\ - -\f0 \uc0\u55357 \u56972 -\f1 \\ud83d\\ude8c bus\ - -\f0 \uc0\u55357 \u56975 -\f1 \\ud83d\\ude8f bus stop\ - -\f0 \uc0\u55357 \u56977 -\f1 \\ud83d\\ude91 ambulance\ - -\f0 \uc0\u55357 \u56978 -\f1 \\ud83d\\ude92 fire engine\ - -\f0 \uc0\u55357 \u56979 -\f1 \\ud83d\\ude93 police car\ - -\f0 \uc0\u55357 \u56981 -\f1 \\ud83d\\ude95 taxi\ - -\f0 \uc0\u55357 \u56983 -\f1 \\ud83d\\ude97 automobile\ - -\f0 \uc0\u55357 \u56985 -\f1 \\ud83d\\ude99 recreational vehicle\ - -\f0 \uc0\u55357 \u56986 -\f1 \\ud83d\\ude9a delivery truck\ - -\f0 \uc0\u55357 \u56994 -\f1 \\ud83d\\udea2 ship\ - -\f0 \uc0\u55357 \u56996 -\f1 \\ud83d\\udea4 speedboat\ - -\f0 \uc0\u55357 \u56997 -\f1 \\ud83d\\udea5 horizontal traffic light\ - -\f0 \uc0\u55357 \u56999 -\f1 \\ud83d\\udea7 construction sign\ - -\f0 \uc0\u55357 \u57000 -\f1 \\ud83d\\udea8 police cars revolving light\ - -\f0 \uc0\u55357 \u57001 -\f1 \\ud83d\\udea9 triangular flag on post\ - -\f0 \uc0\u55357 \u57002 -\f1 \\ud83d\\udeaa door\ - -\f0 \uc0\u55357 \u57003 -\f1 \\ud83d\\udeab no entry sign\ - -\f0 \uc0\u55357 \u57004 -\f1 \\ud83d\\udeac smoking symbol\ - -\f0 \uc0\u55357 \u57005 -\f1 \\ud83d\\udead no smoking symbol\ - -\f0 \uc0\u55357 \u57010 -\f1 \\ud83d\\udeb2 bicycle\ - -\f0 \uc0\u55357 \u57014 -\f1 \\ud83d\\udeb6 pedestrian\ - -\f0 \uc0\u55357 \u57017 -\f1 \\ud83d\\udeb9 mens symbol\ - -\f0 \uc0\u55357 \u57018 -\f1 \\ud83d\\udeba womens symbol\ - -\f0 \uc0\u55357 \u57019 -\f1 \\ud83d\\udebb restroom\ - -\f0 \uc0\u55357 \u57020 -\f1 \\ud83d\\udebc baby symbol\ - -\f0 \uc0\u55357 \u57021 -\f1 \\ud83d\\udebd toilet\ - -\f0 \uc0\u55357 \u57022 -\f1 \\ud83d\\udebe water closet\ - -\f0 \uc0\u55357 \u57024 -\f1 \\ud83d\\udec0 bath\ - -\f3 \uc0\u9410 -\f1 \\u24c2 circled latin capital letter m\ - -\f3 \uc0\u55356 \u56688 -\f1 \\ud83c\\udd70 negative squared latin capital letter a\ - -\f3 \uc0\u55356 \u56689 -\f1 \\ud83c\\udd71 negative squared latin capital letter b\ - -\f3 \uc0\u55356 \u56702 -\f1 \\ud83c\\udd7e negative squared latin capital letter o\ - -\f3 \uc0\u55356 \u56703 -\f1 \\ud83c\\udd7f negative squared latin capital letter p\ - -\f0 \uc0\u55356 \u56718 -\f1 \\ud83c\\udd8e negative squared ab\ - -\f0 \uc0\u55356 \u56721 -\f1 \\ud83c\\udd91 squared cl\ - -\f0 \uc0\u55356 \u56722 -\f1 \\ud83c\\udd92 squared cool\ - -\f0 \uc0\u55356 \u56723 -\f1 \\ud83c\\udd93 squared free\ - -\f0 \uc0\u55356 \u56724 -\f1 \\ud83c\\udd94 squared id\ - -\f0 \uc0\u55356 \u56725 -\f1 \\ud83c\\udd95 squared new\ - -\f0 \uc0\u55356 \u56726 -\f1 \\ud83c\\udd96 squared ng\ - -\f0 \uc0\u55356 \u56727 -\f1 \\ud83c\\udd97 squared ok\ - -\f0 \uc0\u55356 \u56728 -\f1 \\ud83c\\udd98 squared sos\ - -\f0 \uc0\u55356 \u56729 -\f1 \\ud83c\\udd99 squared up with exclamation mark\ - -\f0 \uc0\u55356 \u56730 -\f1 \\ud83c\\udd9a squared vs\ - -\f0 \uc0\u55356 \u56809 \u55356 \u56810 -\f1 \\ud83c\\udde9\\ud83c\\uddea regional indicator symbol letter d + regional indicator symbol letter e\ - -\f0 \uc0\u55356 \u56812 \u55356 \u56807 -\f1 \\ud83c\\uddec\\ud83c\\udde7 regional indicator symbol letter g + regional indicator symbol letter b\ - -\f0 \uc0\u55356 \u56808 \u55356 \u56819 -\f1 \\ud83c\\udde8\\ud83c\\uddf3 regional indicator symbol letter c + regional indicator symbol letter n\ - -\f0 \uc0\u55356 \u56815 \u55356 \u56821 -\f1 \\ud83c\\uddef\\ud83c\\uddf5 regional indicator symbol letter j + regional indicator symbol letter p\ - -\f0 \uc0\u55356 \u56816 \u55356 \u56823 -\f1 \\ud83c\\uddf0\\ud83c\\uddf7 regional indicator symbol letter k + regional indicator symbol letter r\ - -\f0 \uc0\u55356 \u56811 \u55356 \u56823 -\f1 \\ud83c\\uddeb\\ud83c\\uddf7 regional indicator symbol letter f + regional indicator symbol letter r\ - -\f0 \uc0\u55356 \u56810 \u55356 \u56824 -\f1 \\ud83c\\uddea\\ud83c\\uddf8 regional indicator symbol letter e + regional indicator symbol letter s\ - -\f0 \uc0\u55356 \u56814 \u55356 \u56825 -\f1 \\ud83c\\uddee\\ud83c\\uddf9 regional indicator symbol letter i + regional indicator symbol letter t\ - -\f0 \uc0\u55356 \u56826 \u55356 \u56824 -\f1 \\ud83c\\uddfa\\ud83c\\uddf8 regional indicator symbol letter u + regional indicator symbol letter s\ - -\f0 \uc0\u55356 \u56823 \u55356 \u56826 -\f1 \\ud83c\\uddf7\\ud83c\\uddfa regional indicator symbol letter r + regional indicator symbol letter u\ - -\f0 \uc0\u55356 \u56833 -\f1 \\ud83c\\ude01 squared katakana koko\ - -\f3 \uc0\u55356 \u56834 -\f1 \\ud83c\\ude02 squared katakana sa\ - -\f0 \uc0\u55356 \u56858 -\f1 \\ud83c\\ude1a squared cjk unified ideograph-7121\ - -\f0 \uc0\u55356 \u56879 -\f1 \\ud83c\\ude2f squared cjk unified ideograph-6307\ - -\f0 \uc0\u55356 \u56882 -\f1 \\ud83c\\ude32 squared cjk unified ideograph-7981\ - -\f0 \uc0\u55356 \u56883 -\f1 \\ud83c\\ude33 squared cjk unified ideograph-7a7a\ - -\f0 \uc0\u55356 \u56884 -\f1 \\ud83c\\ude34 squared cjk unified ideograph-5408\ - -\f0 \uc0\u55356 \u56885 -\f1 \\ud83c\\ude35 squared cjk unified ideograph-6e80\ - -\f0 \uc0\u55356 \u56886 -\f1 \\ud83c\\ude36 squared cjk unified ideograph-6709\ - -\f3 \uc0\u55356 \u56887 -\f1 \\ud83c\\ude37 squared cjk unified ideograph-6708\ - -\f0 \uc0\u55356 \u56888 -\f1 \\ud83c\\ude38 squared cjk unified ideograph-7533\ - -\f0 \uc0\u55356 \u56889 -\f1 \\ud83c\\ude39 squared cjk unified ideograph-5272\ - -\f0 \uc0\u55356 \u56890 -\f1 \\ud83c\\ude3a squared cjk unified ideograph-55b6\ - -\f0 \uc0\u55356 \u56912 -\f1 \\ud83c\\ude50 circled ideograph advantage\ - -\f0 \uc0\u55356 \u56913 -\f1 \\ud83c\\ude51 circled ideograph accept\ -\'a9 \\ua9 copyright sign\ -\'ae \\uae registered sign\ -\uc0\u8252 \\u203c double exclamation mark\ -\uc0\u8265 \\u2049 exclamation question mark\ - -\f4 8\uc0\u8419 -\f1 \\u38\\u20e3 digit eight + combining enclosing keycap\ - -\f4 9\uc0\u8419 -\f1 \\u39\\u20e3 digit nine + combining enclosing keycap\ - -\f4 7\uc0\u8419 -\f1 \\u37\\u20e3 digit seven + combining enclosing keycap\ - -\f4 6\uc0\u8419 -\f1 \\u36\\u20e3 digit six + combining enclosing keycap\ - -\f4 1\uc0\u8419 -\f1 \\u31\\u20e3 digit one + combining enclosing keycap\ - -\f4 0\uc0\u8419 -\f1 \\u30\\u20e3 digit zero + combining enclosing keycap\ - -\f4 2\uc0\u8419 -\f1 \\u32\\u20e3 digit two + combining enclosing keycap\ - -\f4 3\uc0\u8419 -\f1 \\u33\\u20e3 digit three + combining enclosing keycap\ - -\f4 5\uc0\u8419 -\f1 \\u35\\u20e3 digit five + combining enclosing keycap\ - -\f4 4\uc0\u8419 -\f1 \\u34\\u20e3 digit four + combining enclosing keycap\ - -\f4 #\uc0\u8419 -\f1 \\u23\\u20e3 number sign + combining enclosing keycap\ -\'99 \\u2122 trade mark sign\ - -\f5 \uc0\u8505 -\f1 \\u2139 information source\ - -\f3 \uc0\u8596 -\f1 \\u2194 left right arrow\ - -\f6 \uc0\u8597 -\f1 \\u2195 up down arrow\ - -\f4 \uc0\u8598 -\f1 \\u2196 north west arrow\ - -\f3 \uc0\u8599 -\f1 \\u2197 north east arrow\ - -\f4 \uc0\u8600 -\f1 \\u2198 south east arrow\ - -\f3 \uc0\u8601 -\f1 \\u2199 south west arrow\ - -\f4 \uc0\u8617 -\f1 \\u21a9 leftwards arrow with hook\ - -\f4 \uc0\u8618 -\f1 \\u21aa rightwards arrow with hook\ - -\f0 \uc0\u8986 -\f1 \\u231a watch\ - -\f0 \uc0\u8987 -\f1 \\u231b hourglass\ - -\f0 \uc0\u9193 -\f1 \\u23e9 black right-pointing double triangle\ - -\f0 \uc0\u9194 -\f1 \\u23ea black left-pointing double triangle\ - -\f0 \uc0\u9195 -\f1 \\u23eb black up-pointing double triangle\ - -\f0 \uc0\u9196 -\f1 \\u23ec black down-pointing double triangle\ - -\f0 \uc0\u9200 -\f1 \\u23f0 alarm clock\ - -\f0 \uc0\u9203 -\f1 \\u23f3 hourglass with flowing sand\ - -\f4 \uc0\u9642 -\f1 \\u25aa black small square\ - -\f4 \uc0\u9643 -\f1 \\u25ab white small square\ - -\f4 \uc0\u9654 -\f1 \\u25b6 black right-pointing triangle\ - -\f3 \uc0\u9664 -\f1 \\u25c0 black left-pointing triangle\ - -\f7 \uc0\u9723 -\f1 \\u25fb white medium square\ - -\f7 \uc0\u9724 -\f1 \\u25fc black medium square\ - -\f0 \uc0\u9725 -\f1 \\u25fd white medium small square\ - -\f0 \uc0\u9726 -\f1 \\u25fe black medium small square\ - -\f3 \uc0\u9728 -\f1 \\u2600 black sun with rays\ - -\f3 \uc0\u9729 -\f1 \\u2601 cloud\ - -\f3 \uc0\u9742 -\f1 \\u260e black telephone\ - -\f5 \uc0\u9745 -\f1 \\u2611 ballot box with check\ - -\f0 \uc0\u9748 -\f1 \\u2614 umbrella with rain drops\ - -\f0 \uc0\u9749 -\f1 \\u2615 hot beverage\ - -\f3 \uc0\u9757 -\f1 \\u261d white up pointing index\ - -\f6 \uc0\u9786 -\f1 \\u263a white smiling face\ - -\f0 \uc0\u9800 -\f1 \\u2648 aries\ - -\f0 \uc0\u9801 -\f1 \\u2649 taurus\ - -\f0 \uc0\u9802 -\f1 \\u264a gemini\ - -\f0 \uc0\u9803 -\f1 \\u264b cancer\ - -\f0 \uc0\u9804 -\f1 \\u264c leo\ - -\f0 \uc0\u9805 -\f1 \\u264d virgo\ - -\f0 \uc0\u9806 -\f1 \\u264e libra\ - -\f0 \uc0\u9807 -\f1 \\u264f scorpius\ - -\f0 \uc0\u9808 -\f1 \\u2650 sagittarius\ - -\f0 \uc0\u9809 -\f1 \\u2651 capricorn\ - -\f0 \uc0\u9810 -\f1 \\u2652 aquarius\ - -\f0 \uc0\u9811 -\f1 \\u2653 pisces\ - -\f3 \uc0\u9824 -\f1 \\u2660 black spade suit\ - -\f3 \uc0\u9827 -\f1 \\u2663 black club suit\ - -\f3 \uc0\u9829 -\f1 \\u2665 black heart suit\ - -\f3 \uc0\u9830 -\f1 \\u2666 black diamond suit\ - -\f3 \uc0\u9832 -\f1 \\u2668 hot springs\ - -\f3 \uc0\u9851 -\f1 \\u267b black universal recycling symbol\ - -\f0 \uc0\u9855 -\f1 \\u267f wheelchair symbol\ - -\f0 \uc0\u9875 -\f1 \\u2693 anchor\ - -\f3 \uc0\u9888 -\f1 \\u26a0 warning sign\ - -\f0 \uc0\u9889 -\f1 \\u26a1 high voltage sign\ - -\f0 \uc0\u9898 -\f1 \\u26aa medium white circle\ - -\f0 \uc0\u9899 -\f1 \\u26ab medium black circle\ - -\f0 \uc0\u9917 -\f1 \\u26bd soccer ball\ - -\f3 \uc0\u9918 -\f1 \\u26be baseball\ - -\f0 \uc0\u9924 -\f1 \\u26c4 snowman without snow\ - -\f0 \uc0\u9925 -\f1 \\u26c5 sun behind cloud\ - -\f0 \uc0\u9934 -\f1 \\u26ce ophiuchus\ - -\f0 \uc0\u9940 -\f1 \\u26d4 no entry\ - -\f0 \uc0\u9962 -\f1 \\u26ea church\ - -\f0 \uc0\u9970 -\f1 \\u26f2 fountain\ - -\f0 \uc0\u9971 -\f1 \\u26f3 flag in hole\ - -\f0 \uc0\u9973 -\f1 \\u26f5 sailboat\ - -\f0 \uc0\u9978 -\f1 \\u26fa tent\ - -\f0 \uc0\u9981 -\f1 \\u26fd fuel pump\ - -\f3 \uc0\u10548 -\f1 \\u2934 arrow pointing rightwards then curving upwards\ - -\f3 \uc0\u10549 -\f1 \\u2935 arrow pointing rightwards then curving downwards\ - -\f3 \uc0\u11013 -\f1 \\u2b05 leftwards black arrow\ - -\f3 \uc0\u11014 -\f1 \\u2b06 upwards black arrow\ - -\f3 \uc0\u11015 -\f1 \\u2b07 downwards black arrow\ - -\f0 \uc0\u11035 -\f1 \\u2b1b black large square\ - -\f0 \uc0\u11036 -\f1 \\u2b1c white large square\ - -\f0 \uc0\u11088 -\f1 \\u2b50 white medium star\ - -\f0 \uc0\u11093 -\f1 \\u2b55 heavy large circle\ - -\f3 \uc0\u12336 -\f1 \\u3030 wavy dash\ - -\f3 \uc0\u12349 -\f1 \\u303d part alternation mark\ - -\f3 \uc0\u12951 -\f1 \\u3297 circled ideograph congratulation\ - -\f3 \uc0\u12953 -\f1 \\u3299 circled ideograph secret\ - -\f0 \uc0\u55356 \u56324 -\f1 \\ud83c\\udc04 mahjong tile red dragon\ - -\f0 \uc0\u55356 \u56527 -\f1 \\ud83c\\udccf playing card black joker\ - -\f0 \uc0\u55356 \u57088 -\f1 \\ud83c\\udf00 cyclone\ - -\f0 \uc0\u55356 \u57089 -\f1 \\ud83c\\udf01 foggy\ - -\f0 \uc0\u55356 \u57090 -\f1 \\ud83c\\udf02 closed umbrella\ - -\f0 \uc0\u55356 \u57091 -\f1 \\ud83c\\udf03 night with stars\ - -\f0 \uc0\u55356 \u57092 -\f1 \\ud83c\\udf04 sunrise over mountains\ - -\f0 \uc0\u55356 \u57093 -\f1 \\ud83c\\udf05 sunrise\ - -\f0 \uc0\u55356 \u57094 -\f1 \\ud83c\\udf06 cityscape at dusk\ - -\f0 \uc0\u55356 \u57095 -\f1 \\ud83c\\udf07 sunset over buildings\ - -\f0 \uc0\u55356 \u57096 -\f1 \\ud83c\\udf08 rainbow\ - -\f0 \uc0\u55356 \u57097 -\f1 \\ud83c\\udf09 bridge at night\ - -\f0 \uc0\u55356 \u57098 -\f1 \\ud83c\\udf0a water wave\ - -\f0 \uc0\u55356 \u57099 -\f1 \\ud83c\\udf0b volcano\ - -\f0 \uc0\u55356 \u57100 -\f1 \\ud83c\\udf0c milky way\ - -\f0 \uc0\u55356 \u57103 -\f1 \\ud83c\\udf0f earth globe asia-australia\ - -\f0 \uc0\u55356 \u57105 -\f1 \\ud83c\\udf11 new moon symbol\ - -\f0 \uc0\u55356 \u57107 -\f1 \\ud83c\\udf13 first quarter moon symbol\ - -\f0 \uc0\u55356 \u57108 -\f1 \\ud83c\\udf14 waxing gibbous moon symbol\ - -\f0 \uc0\u55356 \u57109 -\f1 \\ud83c\\udf15 full moon symbol\ - -\f0 \uc0\u55356 \u57113 -\f1 \\ud83c\\udf19 crescent moon\ - -\f0 \uc0\u55356 \u57115 -\f1 \\ud83c\\udf1b first quarter moon with face\ - -\f0 \uc0\u55356 \u57119 -\f1 \\ud83c\\udf1f glowing star\ - -\f0 \uc0\u55356 \u57120 -\f1 \\ud83c\\udf20 shooting star\ - -\f0 \uc0\u55356 \u57136 -\f1 \\ud83c\\udf30 chestnut\ - -\f0 \uc0\u55356 \u57137 -\f1 \\ud83c\\udf31 seedling\ - -\f0 \uc0\u55356 \u57140 -\f1 \\ud83c\\udf34 palm tree\ - -\f0 \uc0\u55356 \u57141 -\f1 \\ud83c\\udf35 cactus\ - -\f0 \uc0\u55356 \u57143 -\f1 \\ud83c\\udf37 tulip\ - -\f0 \uc0\u55356 \u57144 -\f1 \\ud83c\\udf38 cherry blossom\ - -\f0 \uc0\u55356 \u57145 -\f1 \\ud83c\\udf39 rose\ - -\f0 \uc0\u55356 \u57146 -\f1 \\ud83c\\udf3a hibiscus\ - -\f0 \uc0\u55356 \u57147 -\f1 \\ud83c\\udf3b sunflower\ - -\f0 \uc0\u55356 \u57148 -\f1 \\ud83c\\udf3c blossom\ - -\f0 \uc0\u55356 \u57149 -\f1 \\ud83c\\udf3d ear of maize\ - -\f0 \uc0\u55356 \u57150 -\f1 \\ud83c\\udf3e ear of rice\ - -\f0 \uc0\u55356 \u57151 -\f1 \\ud83c\\udf3f herb\ - -\f0 \uc0\u55356 \u57152 -\f1 \\ud83c\\udf40 four leaf clover\ - -\f0 \uc0\u55356 \u57153 -\f1 \\ud83c\\udf41 maple leaf\ - -\f0 \uc0\u55356 \u57154 -\f1 \\ud83c\\udf42 fallen leaf\ - -\f0 \uc0\u55356 \u57155 -\f1 \\ud83c\\udf43 leaf fluttering in wind\ - -\f0 \uc0\u55356 \u57156 -\f1 \\ud83c\\udf44 mushroom\ - -\f0 \uc0\u55356 \u57157 -\f1 \\ud83c\\udf45 tomato\ - -\f0 \uc0\u55356 \u57158 -\f1 \\ud83c\\udf46 aubergine\ - -\f0 \uc0\u55356 \u57159 -\f1 \\ud83c\\udf47 grapes\ - -\f0 \uc0\u55356 \u57160 -\f1 \\ud83c\\udf48 melon\ - -\f0 \uc0\u55356 \u57161 -\f1 \\ud83c\\udf49 watermelon\ - -\f0 \uc0\u55356 \u57162 -\f1 \\ud83c\\udf4a tangerine\ - -\f0 \uc0\u55356 \u57164 -\f1 \\ud83c\\udf4c banana\ - -\f0 \uc0\u55356 \u57165 -\f1 \\ud83c\\udf4d pineapple\ - -\f0 \uc0\u55356 \u57166 -\f1 \\ud83c\\udf4e red apple\ - -\f0 \uc0\u55356 \u57167 -\f1 \\ud83c\\udf4f green apple\ - -\f0 \uc0\u55356 \u57169 -\f1 \\ud83c\\udf51 peach\ - -\f0 \uc0\u55356 \u57170 -\f1 \\ud83c\\udf52 cherries\ - -\f0 \uc0\u55356 \u57171 -\f1 \\ud83c\\udf53 strawberry\ - -\f0 \uc0\u55356 \u57172 -\f1 \\ud83c\\udf54 hamburger\ - -\f0 \uc0\u55356 \u57173 -\f1 \\ud83c\\udf55 slice of pizza\ - -\f0 \uc0\u55356 \u57174 -\f1 \\ud83c\\udf56 meat on bone\ - -\f0 \uc0\u55356 \u57175 -\f1 \\ud83c\\udf57 poultry leg\ - -\f0 \uc0\u55356 \u57176 -\f1 \\ud83c\\udf58 rice cracker\ - -\f0 \uc0\u55356 \u57177 -\f1 \\ud83c\\udf59 rice ball\ - -\f0 \uc0\u55356 \u57178 -\f1 \\ud83c\\udf5a cooked rice\ - -\f0 \uc0\u55356 \u57179 -\f1 \\ud83c\\udf5b curry and rice\ - -\f0 \uc0\u55356 \u57180 -\f1 \\ud83c\\udf5c steaming bowl\ - -\f0 \uc0\u55356 \u57181 -\f1 \\ud83c\\udf5d spaghetti\ - -\f0 \uc0\u55356 \u57182 -\f1 \\ud83c\\udf5e bread\ - -\f0 \uc0\u55356 \u57183 -\f1 \\ud83c\\udf5f french fries\ - -\f0 \uc0\u55356 \u57184 -\f1 \\ud83c\\udf60 roasted sweet potato\ - -\f0 \uc0\u55356 \u57185 -\f1 \\ud83c\\udf61 dango\ - -\f0 \uc0\u55356 \u57186 -\f1 \\ud83c\\udf62 oden\ - -\f0 \uc0\u55356 \u57187 -\f1 \\ud83c\\udf63 sushi\ - -\f0 \uc0\u55356 \u57188 -\f1 \\ud83c\\udf64 fried shrimp\ - -\f0 \uc0\u55356 \u57189 -\f1 \\ud83c\\udf65 fish cake with swirl design\ - -\f0 \uc0\u55356 \u57190 -\f1 \\ud83c\\udf66 soft ice cream\ - -\f0 \uc0\u55356 \u57191 -\f1 \\ud83c\\udf67 shaved ice\ - -\f0 \uc0\u55356 \u57192 -\f1 \\ud83c\\udf68 ice cream\ - -\f0 \uc0\u55356 \u57193 -\f1 \\ud83c\\udf69 doughnut\ - -\f0 \uc0\u55356 \u57194 -\f1 \\ud83c\\udf6a cookie\ - -\f0 \uc0\u55356 \u57195 -\f1 \\ud83c\\udf6b chocolate bar\ - -\f0 \uc0\u55356 \u57196 -\f1 \\ud83c\\udf6c candy\ - -\f0 \uc0\u55356 \u57197 -\f1 \\ud83c\\udf6d lollipop\ - -\f0 \uc0\u55356 \u57198 -\f1 \\ud83c\\udf6e custard\ - -\f0 \uc0\u55356 \u57199 -\f1 \\ud83c\\udf6f honey pot\ - -\f0 \uc0\u55356 \u57200 -\f1 \\ud83c\\udf70 shortcake\ - -\f0 \uc0\u55356 \u57201 -\f1 \\ud83c\\udf71 bento box\ - -\f0 \uc0\u55356 \u57202 -\f1 \\ud83c\\udf72 pot of food\ - -\f0 \uc0\u55356 \u57203 -\f1 \\ud83c\\udf73 cooking\ - -\f0 \uc0\u55356 \u57204 -\f1 \\ud83c\\udf74 fork and knife\ - -\f0 \uc0\u55356 \u57205 -\f1 \\ud83c\\udf75 teacup without handle\ - -\f0 \uc0\u55356 \u57206 -\f1 \\ud83c\\udf76 sake bottle and cup\ - -\f0 \uc0\u55356 \u57207 -\f1 \\ud83c\\udf77 wine glass\ - -\f0 \uc0\u55356 \u57208 -\f1 \\ud83c\\udf78 cocktail glass\ - -\f0 \uc0\u55356 \u57209 -\f1 \\ud83c\\udf79 tropical drink\ - -\f0 \uc0\u55356 \u57210 -\f1 \\ud83c\\udf7a beer mug\ - -\f0 \uc0\u55356 \u57211 -\f1 \\ud83c\\udf7b clinking beer mugs\ - -\f0 \uc0\u55356 \u57216 -\f1 \\ud83c\\udf80 ribbon\ - -\f0 \uc0\u55356 \u57217 -\f1 \\ud83c\\udf81 wrapped present\ - -\f0 \uc0\u55356 \u57218 -\f1 \\ud83c\\udf82 birthday cake\ - -\f0 \uc0\u55356 \u57219 -\f1 \\ud83c\\udf83 jack-o-lantern\ - -\f0 \uc0\u55356 \u57220 -\f1 \\ud83c\\udf84 christmas tree\ - -\f0 \uc0\u55356 \u57221 -\f1 \\ud83c\\udf85 father christmas\ - -\f0 \uc0\u55356 \u57222 -\f1 \\ud83c\\udf86 fireworks\ - -\f0 \uc0\u55356 \u57223 -\f1 \\ud83c\\udf87 firework sparkler\ - -\f0 \uc0\u55356 \u57224 -\f1 \\ud83c\\udf88 balloon\ - -\f0 \uc0\u55356 \u57225 -\f1 \\ud83c\\udf89 party popper\ - -\f0 \uc0\u55356 \u57226 -\f1 \\ud83c\\udf8a confetti ball\ - -\f0 \uc0\u55356 \u57227 -\f1 \\ud83c\\udf8b tanabata tree\ - -\f0 \uc0\u55356 \u57228 -\f1 \\ud83c\\udf8c crossed flags\ - -\f0 \uc0\u55356 \u57229 -\f1 \\ud83c\\udf8d pine decoration\ - -\f0 \uc0\u55356 \u57230 -\f1 \\ud83c\\udf8e japanese dolls\ - -\f0 \uc0\u55356 \u57231 -\f1 \\ud83c\\udf8f carp streamer\ - -\f0 \uc0\u55356 \u57232 -\f1 \\ud83c\\udf90 wind chime\ - -\f0 \uc0\u55356 \u57233 -\f1 \\ud83c\\udf91 moon viewing ceremony\ - -\f0 \uc0\u55356 \u57234 -\f1 \\ud83c\\udf92 school satchel\ - -\f0 \uc0\u55356 \u57235 -\f1 \\ud83c\\udf93 graduation cap\ - -\f0 \uc0\u55356 \u57248 -\f1 \\ud83c\\udfa0 carousel horse\ - -\f0 \uc0\u55356 \u57249 -\f1 \\ud83c\\udfa1 ferris wheel\ - -\f0 \uc0\u55356 \u57250 -\f1 \\ud83c\\udfa2 roller coaster\ - -\f0 \uc0\u55356 \u57251 -\f1 \\ud83c\\udfa3 fishing pole and fish\ - -\f0 \uc0\u55356 \u57252 -\f1 \\ud83c\\udfa4 microphone\ - -\f0 \uc0\u55356 \u57253 -\f1 \\ud83c\\udfa5 movie camera\ - -\f0 \uc0\u55356 \u57254 -\f1 \\ud83c\\udfa6 cinema\ - -\f0 \uc0\u55356 \u57255 -\f1 \\ud83c\\udfa7 headphone\ - -\f0 \uc0\u55356 \u57256 -\f1 \\ud83c\\udfa8 artist palette\ - -\f0 \uc0\u55356 \u57257 -\f1 \\ud83c\\udfa9 top hat\ - -\f0 \uc0\u55356 \u57258 -\f1 \\ud83c\\udfaa circus tent\ - -\f0 \uc0\u55356 \u57259 -\f1 \\ud83c\\udfab ticket\ - -\f0 \uc0\u55356 \u57260 -\f1 \\ud83c\\udfac clapper board\ - -\f0 \uc0\u55356 \u57261 -\f1 \\ud83c\\udfad performing arts\ - -\f0 \uc0\u55356 \u57262 -\f1 \\ud83c\\udfae video game\ - -\f0 \uc0\u55356 \u57263 -\f1 \\ud83c\\udfaf direct hit\ - -\f0 \uc0\u55356 \u57264 -\f1 \\ud83c\\udfb0 slot machine\ - -\f0 \uc0\u55356 \u57265 -\f1 \\ud83c\\udfb1 billiards\ - -\f0 \uc0\u55356 \u57266 -\f1 \\ud83c\\udfb2 game die\ - -\f0 \uc0\u55356 \u57267 -\f1 \\ud83c\\udfb3 bowling\ - -\f0 \uc0\u55356 \u57268 -\f1 \\ud83c\\udfb4 flower playing cards\ - -\f0 \uc0\u55356 \u57269 -\f1 \\ud83c\\udfb5 musical note\ - -\f0 \uc0\u55356 \u57270 -\f1 \\ud83c\\udfb6 multiple musical notes\ - -\f0 \uc0\u55356 \u57271 -\f1 \\ud83c\\udfb7 saxophone\ - -\f0 \uc0\u55356 \u57272 -\f1 \\ud83c\\udfb8 guitar\ - -\f0 \uc0\u55356 \u57273 -\f1 \\ud83c\\udfb9 musical keyboard\ - -\f0 \uc0\u55356 \u57274 -\f1 \\ud83c\\udfba trumpet\ - -\f0 \uc0\u55356 \u57275 -\f1 \\ud83c\\udfbb violin\ - -\f0 \uc0\u55356 \u57276 -\f1 \\ud83c\\udfbc musical score\ - -\f0 \uc0\u55356 \u57277 -\f1 \\ud83c\\udfbd running shirt with sash\ - -\f0 \uc0\u55356 \u57278 -\f1 \\ud83c\\udfbe tennis racquet and ball\ - -\f0 \uc0\u55356 \u57279 -\f1 \\ud83c\\udfbf ski and ski boot\ - -\f0 \uc0\u55356 \u57280 -\f1 \\ud83c\\udfc0 basketball and hoop\ - -\f0 \uc0\u55356 \u57281 -\f1 \\ud83c\\udfc1 chequered flag\ - -\f0 \uc0\u55356 \u57282 -\f1 \\ud83c\\udfc2 snowboarder\ - -\f0 \uc0\u55356 \u57283 -\f1 \\ud83c\\udfc3 runner\ - -\f0 \uc0\u55356 \u57284 -\f1 \\ud83c\\udfc4 surfer\ - -\f0 \uc0\u55356 \u57286 -\f1 \\ud83c\\udfc6 trophy\ - -\f0 \uc0\u55356 \u57288 -\f1 \\ud83c\\udfc8 american football\ - -\f0 \uc0\u55356 \u57290 -\f1 \\ud83c\\udfca swimmer\ - -\f0 \uc0\u55356 \u57312 -\f1 \\ud83c\\udfe0 house building\ - -\f0 \uc0\u55356 \u57313 -\f1 \\ud83c\\udfe1 house with garden\ - -\f0 \uc0\u55356 \u57314 -\f1 \\ud83c\\udfe2 office building\ - -\f0 \uc0\u55356 \u57315 -\f1 \\ud83c\\udfe3 japanese post office\ - -\f0 \uc0\u55356 \u57317 -\f1 \\ud83c\\udfe5 hospital\ - -\f0 \uc0\u55356 \u57318 -\f1 \\ud83c\\udfe6 bank\ - -\f0 \uc0\u55356 \u57319 -\f1 \\ud83c\\udfe7 automated teller machine\ - -\f0 \uc0\u55356 \u57320 -\f1 \\ud83c\\udfe8 hotel\ - -\f0 \uc0\u55356 \u57321 -\f1 \\ud83c\\udfe9 love hotel\ - -\f0 \uc0\u55356 \u57322 -\f1 \\ud83c\\udfea convenience store\ - -\f0 \uc0\u55356 \u57323 -\f1 \\ud83c\\udfeb school\ - -\f0 \uc0\u55356 \u57324 -\f1 \\ud83c\\udfec department store\ - -\f0 \uc0\u55356 \u57325 -\f1 \\ud83c\\udfed factory\ - -\f0 \uc0\u55356 \u57326 -\f1 \\ud83c\\udfee izakaya lantern\ - -\f0 \uc0\u55356 \u57327 -\f1 \\ud83c\\udfef japanese castle\ - -\f0 \uc0\u55356 \u57328 -\f1 \\ud83c\\udff0 european castle\ - -\f0 \uc0\u55357 \u56332 -\f1 \\ud83d\\udc0c snail\ - -\f0 \uc0\u55357 \u56333 -\f1 \\ud83d\\udc0d snake\ - -\f0 \uc0\u55357 \u56334 -\f1 \\ud83d\\udc0e horse\ - -\f0 \uc0\u55357 \u56337 -\f1 \\ud83d\\udc11 sheep\ - -\f0 \uc0\u55357 \u56338 -\f1 \\ud83d\\udc12 monkey\ - -\f0 \uc0\u55357 \u56340 -\f1 \\ud83d\\udc14 chicken\ - -\f0 \uc0\u55357 \u56343 -\f1 \\ud83d\\udc17 boar\ - -\f0 \uc0\u55357 \u56344 -\f1 \\ud83d\\udc18 elephant\ - -\f0 \uc0\u55357 \u56345 -\f1 \\ud83d\\udc19 octopus\ - -\f0 \uc0\u55357 \u56346 -\f1 \\ud83d\\udc1a spiral shell\ - -\f0 \uc0\u55357 \u56347 -\f1 \\ud83d\\udc1b bug\ - -\f0 \uc0\u55357 \u56348 -\f1 \\ud83d\\udc1c ant\ - -\f0 \uc0\u55357 \u56349 -\f1 \\ud83d\\udc1d honeybee\ - -\f0 \uc0\u55357 \u56350 -\f1 \\ud83d\\udc1e lady beetle\ - -\f0 \uc0\u55357 \u56351 -\f1 \\ud83d\\udc1f fish\ - -\f0 \uc0\u55357 \u56352 -\f1 \\ud83d\\udc20 tropical fish\ - -\f0 \uc0\u55357 \u56353 -\f1 \\ud83d\\udc21 blowfish\ - -\f0 \uc0\u55357 \u56354 -\f1 \\ud83d\\udc22 turtle\ - -\f0 \uc0\u55357 \u56355 -\f1 \\ud83d\\udc23 hatching chick\ - -\f0 \uc0\u55357 \u56356 -\f1 \\ud83d\\udc24 baby chick\ - -\f0 \uc0\u55357 \u56357 -\f1 \\ud83d\\udc25 front-facing baby chick\ - -\f0 \uc0\u55357 \u56358 -\f1 \\ud83d\\udc26 bird\ - -\f0 \uc0\u55357 \u56359 -\f1 \\ud83d\\udc27 penguin\ - -\f0 \uc0\u55357 \u56360 -\f1 \\ud83d\\udc28 koala\ - -\f0 \uc0\u55357 \u56361 -\f1 \\ud83d\\udc29 poodle\ - -\f0 \uc0\u55357 \u56363 -\f1 \\ud83d\\udc2b bactrian camel\ - -\f0 \uc0\u55357 \u56364 -\f1 \\ud83d\\udc2c dolphin\ - -\f0 \uc0\u55357 \u56365 -\f1 \\ud83d\\udc2d mouse face\ - -\f0 \uc0\u55357 \u56366 -\f1 \\ud83d\\udc2e cow face\ - -\f0 \uc0\u55357 \u56367 -\f1 \\ud83d\\udc2f tiger face\ - -\f0 \uc0\u55357 \u56368 -\f1 \\ud83d\\udc30 rabbit face\ - -\f0 \uc0\u55357 \u56369 -\f1 \\ud83d\\udc31 cat face\ - -\f0 \uc0\u55357 \u56370 -\f1 \\ud83d\\udc32 dragon face\ - -\f0 \uc0\u55357 \u56371 -\f1 \\ud83d\\udc33 spouting whale\ - -\f0 \uc0\u55357 \u56372 -\f1 \\ud83d\\udc34 horse face\ - -\f0 \uc0\u55357 \u56373 -\f1 \\ud83d\\udc35 monkey face\ - -\f0 \uc0\u55357 \u56374 -\f1 \\ud83d\\udc36 dog face\ - -\f0 \uc0\u55357 \u56375 -\f1 \\ud83d\\udc37 pig face\ - -\f0 \uc0\u55357 \u56376 -\f1 \\ud83d\\udc38 frog face\ - -\f0 \uc0\u55357 \u56377 -\f1 \\ud83d\\udc39 hamster face\ - -\f0 \uc0\u55357 \u56378 -\f1 \\ud83d\\udc3a wolf face\ - -\f0 \uc0\u55357 \u56379 -\f1 \\ud83d\\udc3b bear face\ - -\f0 \uc0\u55357 \u56380 -\f1 \\ud83d\\udc3c panda face\ - -\f0 \uc0\u55357 \u56381 -\f1 \\ud83d\\udc3d pig nose\ - -\f0 \uc0\u55357 \u56382 -\f1 \\ud83d\\udc3e paw prints\ - -\f0 \uc0\u55357 \u56384 -\f1 \\ud83d\\udc40 eyes\ - -\f0 \uc0\u55357 \u56386 -\f1 \\ud83d\\udc42 ear\ - -\f0 \uc0\u55357 \u56387 -\f1 \\ud83d\\udc43 nose\ - -\f0 \uc0\u55357 \u56388 -\f1 \\ud83d\\udc44 mouth\ - -\f0 \uc0\u55357 \u56389 -\f1 \\ud83d\\udc45 tongue\ - -\f0 \uc0\u55357 \u56390 -\f1 \\ud83d\\udc46 white up pointing backhand index\ - -\f0 \uc0\u55357 \u56391 -\f1 \\ud83d\\udc47 white down pointing backhand index\ - -\f0 \uc0\u55357 \u56392 -\f1 \\ud83d\\udc48 white left pointing backhand index\ - -\f0 \uc0\u55357 \u56393 -\f1 \\ud83d\\udc49 white right pointing backhand index\ - -\f0 \uc0\u55357 \u56394 -\f1 \\ud83d\\udc4a fisted hand sign\ - -\f0 \uc0\u55357 \u56395 -\f1 \\ud83d\\udc4b waving hand sign\ - -\f0 \uc0\u55357 \u56396 -\f1 \\ud83d\\udc4c ok hand sign\ - -\f0 \uc0\u55357 \u56397 -\f1 \\ud83d\\udc4d thumbs up sign\ - -\f0 \uc0\u55357 \u56398 -\f1 \\ud83d\\udc4e thumbs down sign\ - -\f0 \uc0\u55357 \u56399 -\f1 \\ud83d\\udc4f clapping hands sign\ - -\f0 \uc0\u55357 \u56400 -\f1 \\ud83d\\udc50 open hands sign\ - -\f0 \uc0\u55357 \u56401 -\f1 \\ud83d\\udc51 crown\ - -\f0 \uc0\u55357 \u56402 -\f1 \\ud83d\\udc52 womans hat\ - -\f0 \uc0\u55357 \u56403 -\f1 \\ud83d\\udc53 eyeglasses\ - -\f0 \uc0\u55357 \u56404 -\f1 \\ud83d\\udc54 necktie\ - -\f0 \uc0\u55357 \u56405 -\f1 \\ud83d\\udc55 t-shirt\ - -\f0 \uc0\u55357 \u56406 -\f1 \\ud83d\\udc56 jeans\ - -\f0 \uc0\u55357 \u56407 -\f1 \\ud83d\\udc57 dress\ - -\f0 \uc0\u55357 \u56408 -\f1 \\ud83d\\udc58 kimono\ - -\f0 \uc0\u55357 \u56409 -\f1 \\ud83d\\udc59 bikini\ - -\f0 \uc0\u55357 \u56410 -\f1 \\ud83d\\udc5a womans clothes\ - -\f0 \uc0\u55357 \u56411 -\f1 \\ud83d\\udc5b purse\ - -\f0 \uc0\u55357 \u56412 -\f1 \\ud83d\\udc5c handbag\ - -\f0 \uc0\u55357 \u56413 -\f1 \\ud83d\\udc5d pouch\ - -\f0 \uc0\u55357 \u56414 -\f1 \\ud83d\\udc5e mans shoe\ - -\f0 \uc0\u55357 \u56415 -\f1 \\ud83d\\udc5f athletic shoe\ - -\f0 \uc0\u55357 \u56416 -\f1 \\ud83d\\udc60 high-heeled shoe\ - -\f0 \uc0\u55357 \u56417 -\f1 \\ud83d\\udc61 womans sandal\ - -\f0 \uc0\u55357 \u56418 -\f1 \\ud83d\\udc62 womans boots\ - -\f0 \uc0\u55357 \u56419 -\f1 \\ud83d\\udc63 footprints\ - -\f0 \uc0\u55357 \u56420 -\f1 \\ud83d\\udc64 bust in silhouette\ - -\f0 \uc0\u55357 \u56422 -\f1 \\ud83d\\udc66 boy\ - -\f0 \uc0\u55357 \u56423 -\f1 \\ud83d\\udc67 girl\ - -\f0 \uc0\u55357 \u56424 -\f1 \\ud83d\\udc68 man\ - -\f0 \uc0\u55357 \u56425 -\f1 \\ud83d\\udc69 woman\ - -\f0 \uc0\u55357 \u56426 -\f1 \\ud83d\\udc6a family\ - -\f0 \uc0\u55357 \u56427 -\f1 \\ud83d\\udc6b man and woman holding hands\ - -\f0 \uc0\u55357 \u56430 -\f1 \\ud83d\\udc6e police officer\ - -\f0 \uc0\u55357 \u56431 -\f1 \\ud83d\\udc6f woman with bunny ears\ - -\f0 \uc0\u55357 \u56432 -\f1 \\ud83d\\udc70 bride with veil\ - -\f0 \uc0\u55357 \u56433 -\f1 \\ud83d\\udc71 person with blond hair\ - -\f0 \uc0\u55357 \u56434 -\f1 \\ud83d\\udc72 man with gua pi mao\ - -\f0 \uc0\u55357 \u56435 -\f1 \\ud83d\\udc73 man with turban\ - -\f0 \uc0\u55357 \u56436 -\f1 \\ud83d\\udc74 older man\ - -\f0 \uc0\u55357 \u56437 -\f1 \\ud83d\\udc75 older woman\ - -\f0 \uc0\u55357 \u56438 -\f1 \\ud83d\\udc76 baby\ - -\f0 \uc0\u55357 \u56439 -\f1 \\ud83d\\udc77 construction worker\ - -\f0 \uc0\u55357 \u56440 -\f1 \\ud83d\\udc78 princess\ - -\f0 \uc0\u55357 \u56441 -\f1 \\ud83d\\udc79 japanese ogre\ - -\f0 \uc0\u55357 \u56442 -\f1 \\ud83d\\udc7a japanese goblin\ - -\f0 \uc0\u55357 \u56443 -\f1 \\ud83d\\udc7b ghost\ - -\f0 \uc0\u55357 \u56444 -\f1 \\ud83d\\udc7c baby angel\ - -\f0 \uc0\u55357 \u56445 -\f1 \\ud83d\\udc7d extraterrestrial alien\ - -\f0 \uc0\u55357 \u56446 -\f1 \\ud83d\\udc7e alien monster\ - -\f0 \uc0\u55357 \u56447 -\f1 \\ud83d\\udc7f imp\ - -\f0 \uc0\u55357 \u56448 -\f1 \\ud83d\\udc80 skull\ - -\f0 \uc0\u55357 \u56449 -\f1 \\ud83d\\udc81 information desk person\ - -\f0 \uc0\u55357 \u56450 -\f1 \\ud83d\\udc82 guardsman\ - -\f0 \uc0\u55357 \u56451 -\f1 \\ud83d\\udc83 dancer\ - -\f0 \uc0\u55357 \u56452 -\f1 \\ud83d\\udc84 lipstick\ - -\f0 \uc0\u55357 \u56453 -\f1 \\ud83d\\udc85 nail polish\ - -\f0 \uc0\u55357 \u56454 -\f1 \\ud83d\\udc86 face massage\ - -\f0 \uc0\u55357 \u56455 -\f1 \\ud83d\\udc87 haircut\ - -\f0 \uc0\u55357 \u56456 -\f1 \\ud83d\\udc88 barber pole\ - -\f0 \uc0\u55357 \u56457 -\f1 \\ud83d\\udc89 syringe\ - -\f0 \uc0\u55357 \u56458 -\f1 \\ud83d\\udc8a pill\ - -\f0 \uc0\u55357 \u56459 -\f1 \\ud83d\\udc8b kiss mark\ - -\f0 \uc0\u55357 \u56460 -\f1 \\ud83d\\udc8c love letter\ - -\f0 \uc0\u55357 \u56461 -\f1 \\ud83d\\udc8d ring\ - -\f0 \uc0\u55357 \u56462 -\f1 \\ud83d\\udc8e gem stone\ - -\f0 \uc0\u55357 \u56463 -\f1 \\ud83d\\udc8f kiss\ - -\f0 \uc0\u55357 \u56464 -\f1 \\ud83d\\udc90 bouquet\ - -\f0 \uc0\u55357 \u56465 -\f1 \\ud83d\\udc91 couple with heart\ - -\f0 \uc0\u55357 \u56466 -\f1 \\ud83d\\udc92 wedding\ - -\f0 \uc0\u55357 \u56467 -\f1 \\ud83d\\udc93 beating heart\ - -\f0 \uc0\u55357 \u56468 -\f1 \\ud83d\\udc94 broken heart\ - -\f0 \uc0\u55357 \u56469 -\f1 \\ud83d\\udc95 two hearts\ - -\f0 \uc0\u55357 \u56470 -\f1 \\ud83d\\udc96 sparkling heart\ - -\f0 \uc0\u55357 \u56471 -\f1 \\ud83d\\udc97 growing heart\ - -\f0 \uc0\u55357 \u56472 -\f1 \\ud83d\\udc98 heart with arrow\ - -\f0 \uc0\u55357 \u56473 -\f1 \\ud83d\\udc99 blue heart\ - -\f0 \uc0\u55357 \u56474 -\f1 \\ud83d\\udc9a green heart\ - -\f0 \uc0\u55357 \u56475 -\f1 \\ud83d\\udc9b yellow heart\ - -\f0 \uc0\u55357 \u56476 -\f1 \\ud83d\\udc9c purple heart\ - -\f0 \uc0\u55357 \u56477 -\f1 \\ud83d\\udc9d heart with ribbon\ - -\f0 \uc0\u55357 \u56478 -\f1 \\ud83d\\udc9e revolving hearts\ - -\f0 \uc0\u55357 \u56479 -\f1 \\ud83d\\udc9f heart decoration\ - -\f0 \uc0\u55357 \u56480 -\f1 \\ud83d\\udca0 diamond shape with a dot inside\ - -\f0 \uc0\u55357 \u56481 -\f1 \\ud83d\\udca1 electric light bulb\ - -\f0 \uc0\u55357 \u56482 -\f1 \\ud83d\\udca2 anger symbol\ - -\f0 \uc0\u55357 \u56483 -\f1 \\ud83d\\udca3 bomb\ - -\f0 \uc0\u55357 \u56484 -\f1 \\ud83d\\udca4 sleeping symbol\ - -\f0 \uc0\u55357 \u56485 -\f1 \\ud83d\\udca5 collision symbol\ - -\f0 \uc0\u55357 \u56486 -\f1 \\ud83d\\udca6 splashing sweat symbol\ - -\f0 \uc0\u55357 \u56487 -\f1 \\ud83d\\udca7 droplet\ - -\f0 \uc0\u55357 \u56488 -\f1 \\ud83d\\udca8 dash symbol\ - -\f0 \uc0\u55357 \u56489 -\f1 \\ud83d\\udca9 pile of poo\ - -\f0 \uc0\u55357 \u56490 -\f1 \\ud83d\\udcaa flexed biceps\ - -\f0 \uc0\u55357 \u56491 -\f1 \\ud83d\\udcab dizzy symbol\ - -\f0 \uc0\u55357 \u56492 -\f1 \\ud83d\\udcac speech balloon\ - -\f0 \uc0\u55357 \u56494 -\f1 \\ud83d\\udcae white flower\ - -\f0 \uc0\u55357 \u56495 -\f1 \\ud83d\\udcaf hundred points symbol\ - -\f0 \uc0\u55357 \u56496 -\f1 \\ud83d\\udcb0 money bag\ - -\f0 \uc0\u55357 \u56497 -\f1 \\ud83d\\udcb1 currency exchange\ - -\f0 \uc0\u55357 \u56498 -\f1 \\ud83d\\udcb2 heavy dollar sign\ - -\f0 \uc0\u55357 \u56499 -\f1 \\ud83d\\udcb3 credit card\ - -\f0 \uc0\u55357 \u56500 -\f1 \\ud83d\\udcb4 banknote with yen sign\ - -\f0 \uc0\u55357 \u56501 -\f1 \\ud83d\\udcb5 banknote with dollar sign\ - -\f0 \uc0\u55357 \u56504 -\f1 \\ud83d\\udcb8 money with wings\ - -\f0 \uc0\u55357 \u56505 -\f1 \\ud83d\\udcb9 chart with upwards trend and yen sign\ - -\f0 \uc0\u55357 \u56506 -\f1 \\ud83d\\udcba seat\ - -\f0 \uc0\u55357 \u56507 -\f1 \\ud83d\\udcbb personal computer\ - -\f0 \uc0\u55357 \u56508 -\f1 \\ud83d\\udcbc briefcase\ - -\f0 \uc0\u55357 \u56509 -\f1 \\ud83d\\udcbd minidisc\ - -\f0 \uc0\u55357 \u56510 -\f1 \\ud83d\\udcbe floppy disk\ - -\f0 \uc0\u55357 \u56511 -\f1 \\ud83d\\udcbf optical disc\ - -\f0 \uc0\u55357 \u56512 -\f1 \\ud83d\\udcc0 dvd\ - -\f0 \uc0\u55357 \u56513 -\f1 \\ud83d\\udcc1 file folder\ - -\f0 \uc0\u55357 \u56514 -\f1 \\ud83d\\udcc2 open file folder\ - -\f0 \uc0\u55357 \u56515 -\f1 \\ud83d\\udcc3 page with curl\ - -\f0 \uc0\u55357 \u56516 -\f1 \\ud83d\\udcc4 page facing up\ - -\f0 \uc0\u55357 \u56517 -\f1 \\ud83d\\udcc5 calendar\ - -\f0 \uc0\u55357 \u56518 -\f1 \\ud83d\\udcc6 tear-off calendar\ - -\f0 \uc0\u55357 \u56519 -\f1 \\ud83d\\udcc7 card index\ - -\f0 \uc0\u55357 \u56520 -\f1 \\ud83d\\udcc8 chart with upwards trend\ - -\f0 \uc0\u55357 \u56521 -\f1 \\ud83d\\udcc9 chart with downwards trend\ - -\f0 \uc0\u55357 \u56522 -\f1 \\ud83d\\udcca bar chart\ - -\f0 \uc0\u55357 \u56523 -\f1 \\ud83d\\udccb clipboard\ - -\f0 \uc0\u55357 \u56524 -\f1 \\ud83d\\udccc pushpin\ - -\f0 \uc0\u55357 \u56525 -\f1 \\ud83d\\udccd round pushpin\ - -\f0 \uc0\u55357 \u56526 -\f1 \\ud83d\\udcce paperclip\ - -\f0 \uc0\u55357 \u56527 -\f1 \\ud83d\\udccf straight ruler\ - -\f0 \uc0\u55357 \u56528 -\f1 \\ud83d\\udcd0 triangular ruler\ - -\f0 \uc0\u55357 \u56529 -\f1 \\ud83d\\udcd1 bookmark tabs\ - -\f0 \uc0\u55357 \u56530 -\f1 \\ud83d\\udcd2 ledger\ - -\f0 \uc0\u55357 \u56531 -\f1 \\ud83d\\udcd3 notebook\ - -\f0 \uc0\u55357 \u56532 -\f1 \\ud83d\\udcd4 notebook with decorative cover\ - -\f0 \uc0\u55357 \u56533 -\f1 \\ud83d\\udcd5 closed book\ - -\f0 \uc0\u55357 \u56534 -\f1 \\ud83d\\udcd6 open book\ - -\f0 \uc0\u55357 \u56535 -\f1 \\ud83d\\udcd7 green book\ - -\f0 \uc0\u55357 \u56536 -\f1 \\ud83d\\udcd8 blue book\ - -\f0 \uc0\u55357 \u56537 -\f1 \\ud83d\\udcd9 orange book\ - -\f0 \uc0\u55357 \u56538 -\f1 \\ud83d\\udcda books\ - -\f0 \uc0\u55357 \u56539 -\f1 \\ud83d\\udcdb name badge\ - -\f0 \uc0\u55357 \u56540 -\f1 \\ud83d\\udcdc scroll\ - -\f0 \uc0\u55357 \u56541 -\f1 \\ud83d\\udcdd memo\ - -\f0 \uc0\u55357 \u56542 -\f1 \\ud83d\\udcde telephone receiver\ - -\f0 \uc0\u55357 \u56543 -\f1 \\ud83d\\udcdf pager\ - -\f0 \uc0\u55357 \u56544 -\f1 \\ud83d\\udce0 fax machine\ - -\f0 \uc0\u55357 \u56545 -\f1 \\ud83d\\udce1 satellite antenna\ - -\f0 \uc0\u55357 \u56546 -\f1 \\ud83d\\udce2 public address loudspeaker\ - -\f0 \uc0\u55357 \u56547 -\f1 \\ud83d\\udce3 cheering megaphone\ - -\f0 \uc0\u55357 \u56548 -\f1 \\ud83d\\udce4 outbox tray\ - -\f0 \uc0\u55357 \u56549 -\f1 \\ud83d\\udce5 inbox tray\ - -\f0 \uc0\u55357 \u56550 -\f1 \\ud83d\\udce6 package\ - -\f0 \uc0\u55357 \u56551 -\f1 \\ud83d\\udce7 e-mail symbol\ - -\f0 \uc0\u55357 \u56552 -\f1 \\ud83d\\udce8 incoming envelope\ - -\f0 \uc0\u55357 \u56553 -\f1 \\ud83d\\udce9 envelope with downwards arrow above\ - -\f0 \uc0\u55357 \u56554 -\f1 \\ud83d\\udcea closed mailbox with lowered flag\ - -\f0 \uc0\u55357 \u56555 -\f1 \\ud83d\\udceb closed mailbox with raised flag\ - -\f0 \uc0\u55357 \u56558 -\f1 \\ud83d\\udcee postbox\ - -\f0 \uc0\u55357 \u56560 -\f1 \\ud83d\\udcf0 newspaper\ - -\f0 \uc0\u55357 \u56561 -\f1 \\ud83d\\udcf1 mobile phone\ - -\f0 \uc0\u55357 \u56562 -\f1 \\ud83d\\udcf2 mobile phone with rightwards arrow at left\ - -\f0 \uc0\u55357 \u56563 -\f1 \\ud83d\\udcf3 vibration mode\ - -\f0 \uc0\u55357 \u56564 -\f1 \\ud83d\\udcf4 mobile phone off\ - -\f0 \uc0\u55357 \u56566 -\f1 \\ud83d\\udcf6 antenna with bars\ - -\f0 \uc0\u55357 \u56567 -\f1 \\ud83d\\udcf7 camera\ - -\f0 \uc0\u55357 \u56569 -\f1 \\ud83d\\udcf9 video camera\ - -\f0 \uc0\u55357 \u56570 -\f1 \\ud83d\\udcfa television\ - -\f0 \uc0\u55357 \u56571 -\f1 \\ud83d\\udcfb radio\ - -\f0 \uc0\u55357 \u56572 -\f1 \\ud83d\\udcfc videocassette\ - -\f0 \uc0\u55357 \u56579 -\f1 \\ud83d\\udd03 clockwise downwards and upwards open circle arrows\ - -\f0 \uc0\u55357 \u56586 -\f1 \\ud83d\\udd0a speaker with three sound waves\ - -\f0 \uc0\u55357 \u56587 -\f1 \\ud83d\\udd0b battery\ - -\f0 \uc0\u55357 \u56588 -\f1 \\ud83d\\udd0c electric plug\ - -\f0 \uc0\u55357 \u56589 -\f1 \\ud83d\\udd0d left-pointing magnifying glass\ - -\f0 \uc0\u55357 \u56590 -\f1 \\ud83d\\udd0e right-pointing magnifying glass\ - -\f0 \uc0\u55357 \u56591 -\f1 \\ud83d\\udd0f lock with ink pen\ - -\f0 \uc0\u55357 \u56592 -\f1 \\ud83d\\udd10 closed lock with key\ - -\f0 \uc0\u55357 \u56593 -\f1 \\ud83d\\udd11 key\ - -\f0 \uc0\u55357 \u56594 -\f1 \\ud83d\\udd12 lock\ - -\f0 \uc0\u55357 \u56595 -\f1 \\ud83d\\udd13 open lock\ - -\f0 \uc0\u55357 \u56596 -\f1 \\ud83d\\udd14 bell\ - -\f0 \uc0\u55357 \u56598 -\f1 \\ud83d\\udd16 bookmark\ - -\f0 \uc0\u55357 \u56599 -\f1 \\ud83d\\udd17 link symbol\ - -\f0 \uc0\u55357 \u56600 -\f1 \\ud83d\\udd18 radio button\ - -\f0 \uc0\u55357 \u56601 -\f1 \\ud83d\\udd19 back with leftwards arrow above\ - -\f0 \uc0\u55357 \u56602 -\f1 \\ud83d\\udd1a end with leftwards arrow above\ - -\f0 \uc0\u55357 \u56603 -\f1 \\ud83d\\udd1b on with exclamation mark with left right arrow above\ - -\f0 \uc0\u55357 \u56604 -\f1 \\ud83d\\udd1c soon with rightwards arrow above\ - -\f0 \uc0\u55357 \u56605 -\f1 \\ud83d\\udd1d top with upwards arrow above\ - -\f0 \uc0\u55357 \u56606 -\f1 \\ud83d\\udd1e no one under eighteen symbol\ - -\f0 \uc0\u55357 \u56607 -\f1 \\ud83d\\udd1f keycap ten\ - -\f0 \uc0\u55357 \u56608 -\f1 \\ud83d\\udd20 input symbol for latin capital letters\ - -\f0 \uc0\u55357 \u56609 -\f1 \\ud83d\\udd21 input symbol for latin small letters\ - -\f0 \uc0\u55357 \u56610 -\f1 \\ud83d\\udd22 input symbol for numbers\ - -\f0 \uc0\u55357 \u56611 -\f1 \\ud83d\\udd23 input symbol for symbols\ - -\f0 \uc0\u55357 \u56612 -\f1 \\ud83d\\udd24 input symbol for latin letters\ - -\f0 \uc0\u55357 \u56613 -\f1 \\ud83d\\udd25 fire\ - -\f0 \uc0\u55357 \u56614 -\f1 \\ud83d\\udd26 electric torch\ - -\f0 \uc0\u55357 \u56615 -\f1 \\ud83d\\udd27 wrench\ - -\f0 \uc0\u55357 \u56616 -\f1 \\ud83d\\udd28 hammer\ - -\f0 \uc0\u55357 \u56617 -\f1 \\ud83d\\udd29 nut and bolt\ - -\f0 \uc0\u55357 \u56618 -\f1 \\ud83d\\udd2a hocho\ - -\f0 \uc0\u55357 \u56619 -\f1 \\ud83d\\udd2b pistol\ - -\f0 \uc0\u55357 \u56622 -\f1 \\ud83d\\udd2e crystal ball\ - -\f0 \uc0\u55357 \u56623 -\f1 \\ud83d\\udd2f six pointed star with middle dot\ - -\f0 \uc0\u55357 \u56624 -\f1 \\ud83d\\udd30 japanese symbol for beginner\ - -\f0 \uc0\u55357 \u56625 -\f1 \\ud83d\\udd31 trident emblem\ - -\f0 \uc0\u55357 \u56626 -\f1 \\ud83d\\udd32 black square button\ - -\f0 \uc0\u55357 \u56627 -\f1 \\ud83d\\udd33 white square button\ - -\f0 \uc0\u55357 \u56628 -\f1 \\ud83d\\udd34 large red circle\ - -\f0 \uc0\u55357 \u56629 -\f1 \\ud83d\\udd35 large blue circle\ - -\f0 \uc0\u55357 \u56630 -\f1 \\ud83d\\udd36 large orange diamond\ - -\f0 \uc0\u55357 \u56631 -\f1 \\ud83d\\udd37 large blue diamond\ - -\f0 \uc0\u55357 \u56632 -\f1 \\ud83d\\udd38 small orange diamond\ - -\f0 \uc0\u55357 \u56633 -\f1 \\ud83d\\udd39 small blue diamond\ - -\f0 \uc0\u55357 \u56634 -\f1 \\ud83d\\udd3a up-pointing red triangle\ - -\f0 \uc0\u55357 \u56635 -\f1 \\ud83d\\udd3b down-pointing red triangle\ - -\f0 \uc0\u55357 \u56636 -\f1 \\ud83d\\udd3c up-pointing small red triangle\ - -\f0 \uc0\u55357 \u56637 -\f1 \\ud83d\\udd3d down-pointing small red triangle\ - -\f0 \uc0\u55357 \u56656 -\f1 \\ud83d\\udd50 clock face one oclock\ - -\f0 \uc0\u55357 \u56657 -\f1 \\ud83d\\udd51 clock face two oclock\ - -\f0 \uc0\u55357 \u56658 -\f1 \\ud83d\\udd52 clock face three oclock\ - -\f0 \uc0\u55357 \u56659 -\f1 \\ud83d\\udd53 clock face four oclock\ - -\f0 \uc0\u55357 \u56660 -\f1 \\ud83d\\udd54 clock face five oclock\ - -\f0 \uc0\u55357 \u56661 -\f1 \\ud83d\\udd55 clock face six oclock\ - -\f0 \uc0\u55357 \u56662 -\f1 \\ud83d\\udd56 clock face seven oclock\ - -\f0 \uc0\u55357 \u56663 -\f1 \\ud83d\\udd57 clock face eight oclock\ - -\f0 \uc0\u55357 \u56664 -\f1 \\ud83d\\udd58 clock face nine oclock\ - -\f0 \uc0\u55357 \u56665 -\f1 \\ud83d\\udd59 clock face ten oclock\ - -\f0 \uc0\u55357 \u56666 -\f1 \\ud83d\\udd5a clock face eleven oclock\ - -\f0 \uc0\u55357 \u56667 -\f1 \\ud83d\\udd5b clock face twelve oclock\ - -\f0 \uc0\u55357 \u56827 -\f1 \\ud83d\\uddfb mount fuji\ - -\f0 \uc0\u55357 \u56828 -\f1 \\ud83d\\uddfc tokyo tower\ - -\f0 \uc0\u55357 \u56829 -\f1 \\ud83d\\uddfd statue of liberty\ - -\f0 \uc0\u55357 \u56830 -\f1 \\ud83d\\uddfe silhouette of japan\ - -\f0 \uc0\u55357 \u56831 -\f1 \\ud83d\\uddff moyai\ - -\f0 \uc0\u55357 \u56832 -\f1 \\ud83d\\ude00 grinning face\ - -\f0 \uc0\u55357 \u56839 -\f1 \\ud83d\\ude07 smiling face with halo\ - -\f0 \uc0\u55357 \u56840 -\f1 \\ud83d\\ude08 smiling face with horns\ - -\f0 \uc0\u55357 \u56846 -\f1 \\ud83d\\ude0e smiling face with sunglasses\ - -\f0 \uc0\u55357 \u56848 -\f1 \\ud83d\\ude10 neutral face\ - -\f0 \uc0\u55357 \u56849 -\f1 \\ud83d\\ude11 expressionless face\ - -\f0 \uc0\u55357 \u56853 -\f1 \\ud83d\\ude15 confused face\ - -\f0 \uc0\u55357 \u56855 -\f1 \\ud83d\\ude17 kissing face\ - -\f0 \uc0\u55357 \u56857 -\f1 \\ud83d\\ude19 kissing face with smiling eyes\ - -\f0 \uc0\u55357 \u56859 -\f1 \\ud83d\\ude1b face with stuck-out tongue\ - -\f0 \uc0\u55357 \u56863 -\f1 \\ud83d\\ude1f worried face\ - -\f0 \uc0\u55357 \u56870 -\f1 \\ud83d\\ude26 frowning face with open mouth\ - -\f0 \uc0\u55357 \u56871 -\f1 \\ud83d\\ude27 anguished face\ - -\f0 \uc0\u55357 \u56876 -\f1 \\ud83d\\ude2c grimacing face\ - -\f0 \uc0\u55357 \u56878 -\f1 \\ud83d\\ude2e face with open mouth\ - -\f0 \uc0\u55357 \u56879 -\f1 \\ud83d\\ude2f hushed face\ - -\f0 \uc0\u55357 \u56884 -\f1 \\ud83d\\ude34 sleeping face\ - -\f0 \uc0\u55357 \u56886 -\f1 \\ud83d\\ude36 face without mouth\ - -\f0 \uc0\u55357 \u56961 -\f1 \\ud83d\\ude81 helicopter\ - -\f0 \uc0\u55357 \u56962 -\f1 \\ud83d\\ude82 steam locomotive\ - -\f0 \uc0\u55357 \u56966 -\f1 \\ud83d\\ude86 train\ - -\f0 \uc0\u55357 \u56968 -\f1 \\ud83d\\ude88 light rail\ - -\f0 \uc0\u55357 \u56970 -\f1 \\ud83d\\ude8a tram\ - -\f0 \uc0\u55357 \u56973 -\f1 \\ud83d\\ude8d oncoming bus\ - -\f0 \uc0\u55357 \u56974 -\f1 \\ud83d\\ude8e trolleybus\ - -\f0 \uc0\u55357 \u56976 -\f1 \\ud83d\\ude90 minibus\ - -\f0 \uc0\u55357 \u56980 -\f1 \\ud83d\\ude94 oncoming police car\ - -\f0 \uc0\u55357 \u56982 -\f1 \\ud83d\\ude96 oncoming taxi\ - -\f0 \uc0\u55357 \u56984 -\f1 \\ud83d\\ude98 oncoming automobile\ - -\f0 \uc0\u55357 \u56987 -\f1 \\ud83d\\ude9b articulated lorry\ - -\f0 \uc0\u55357 \u56988 -\f1 \\ud83d\\ude9c tractor\ - -\f0 \uc0\u55357 \u56989 -\f1 \\ud83d\\ude9d monorail\ - -\f0 \uc0\u55357 \u56990 -\f1 \\ud83d\\ude9e mountain railway\ - -\f0 \uc0\u55357 \u56991 -\f1 \\ud83d\\ude9f suspension railway\ - -\f0 \uc0\u55357 \u56992 -\f1 \\ud83d\\udea0 mountain cableway\ - -\f0 \uc0\u55357 \u56993 -\f1 \\ud83d\\udea1 aerial tramway\ - -\f0 \uc0\u55357 \u56995 -\f1 \\ud83d\\udea3 rowboat\ - -\f0 \uc0\u55357 \u56998 -\f1 \\ud83d\\udea6 vertical traffic light\ - -\f0 \uc0\u55357 \u57006 -\f1 \\ud83d\\udeae put litter in its place symbol\ - -\f0 \uc0\u55357 \u57007 -\f1 \\ud83d\\udeaf do not litter symbol\ - -\f0 \uc0\u55357 \u57008 -\f1 \\ud83d\\udeb0 potable water symbol\ - -\f0 \uc0\u55357 \u57009 -\f1 \\ud83d\\udeb1 non-potable water symbol\ - -\f0 \uc0\u55357 \u57011 -\f1 \\ud83d\\udeb3 no bicycles\ - -\f0 \uc0\u55357 \u57012 -\f1 \\ud83d\\udeb4 bicyclist\ - -\f0 \uc0\u55357 \u57013 -\f1 \\ud83d\\udeb5 mountain bicyclist\ - -\f0 \uc0\u55357 \u57015 -\f1 \\ud83d\\udeb7 no pedestrians\ - -\f0 \uc0\u55357 \u57016 -\f1 \\ud83d\\udeb8 children crossing\ - -\f0 \uc0\u55357 \u57023 -\f1 \\ud83d\\udebf shower\ - -\f0 \uc0\u55357 \u57025 -\f1 \\ud83d\\udec1 bathtub\ - -\f0 \uc0\u55357 \u57026 -\f1 \\ud83d\\udec2 passport control\ - -\f0 \uc0\u55357 \u57027 -\f1 \\ud83d\\udec3 customs\ - -\f0 \uc0\u55357 \u57028 -\f1 \\ud83d\\udec4 baggage claim\ - -\f0 \uc0\u55357 \u57029 -\f1 \\ud83d\\udec5 left luggage\ - -\f0 \uc0\u55356 \u57101 -\f1 \\ud83c\\udf0d earth globe europe-africa\ - -\f0 \uc0\u55356 \u57102 -\f1 \\ud83c\\udf0e earth globe americas\ - -\f0 \uc0\u55356 \u57104 -\f1 \\ud83c\\udf10 globe with meridians\ - -\f0 \uc0\u55356 \u57106 -\f1 \\ud83c\\udf12 waxing crescent moon symbol\ - -\f0 \uc0\u55356 \u57110 -\f1 \\ud83c\\udf16 waning gibbous moon symbol\ - -\f0 \uc0\u55356 \u57111 -\f1 \\ud83c\\udf17 last quarter moon symbol\ - -\f0 \uc0\u55356 \u57112 -\f1 \\ud83c\\udf18 waning crescent moon symbol\ - -\f0 \uc0\u55356 \u57114 -\f1 \\ud83c\\udf1a new moon with face\ - -\f0 \uc0\u55356 \u57116 -\f1 \\ud83c\\udf1c last quarter moon with face\ - -\f0 \uc0\u55356 \u57117 -\f1 \\ud83c\\udf1d full moon with face\ - -\f0 \uc0\u55356 \u57118 -\f1 \\ud83c\\udf1e sun with face\ - -\f0 \uc0\u55356 \u57138 -\f1 \\ud83c\\udf32 evergreen tree\ - -\f0 \uc0\u55356 \u57139 -\f1 \\ud83c\\udf33 deciduous tree\ - -\f0 \uc0\u55356 \u57163 -\f1 \\ud83c\\udf4b lemon\ - -\f0 \uc0\u55356 \u57168 -\f1 \\ud83c\\udf50 pear\ - -\f0 \uc0\u55356 \u57212 -\f1 \\ud83c\\udf7c baby bottle\ - -\f0 \uc0\u55356 \u57287 -\f1 \\ud83c\\udfc7 horse racing\ - -\f0 \uc0\u55356 \u57289 -\f1 \\ud83c\\udfc9 rugby football\ - -\f0 \uc0\u55356 \u57316 -\f1 \\ud83c\\udfe4 european post office\ - -\f0 \uc0\u55357 \u56320 -\f1 \\ud83d\\udc00 rat\ - -\f0 \uc0\u55357 \u56321 -\f1 \\ud83d\\udc01 mouse\ - -\f0 \uc0\u55357 \u56322 -\f1 \\ud83d\\udc02 ox\ - -\f0 \uc0\u55357 \u56323 -\f1 \\ud83d\\udc03 water buffalo\ - -\f0 \uc0\u55357 \u56324 -\f1 \\ud83d\\udc04 cow\ - -\f0 \uc0\u55357 \u56325 -\f1 \\ud83d\\udc05 tiger\ - -\f0 \uc0\u55357 \u56326 -\f1 \\ud83d\\udc06 leopard\ - -\f0 \uc0\u55357 \u56327 -\f1 \\ud83d\\udc07 rabbit\ - -\f0 \uc0\u55357 \u56328 -\f1 \\ud83d\\udc08 cat\ - -\f0 \uc0\u55357 \u56329 -\f1 \\ud83d\\udc09 dragon\ - -\f0 \uc0\u55357 \u56330 -\f1 \\ud83d\\udc0a crocodile\ - -\f0 \uc0\u55357 \u56331 -\f1 \\ud83d\\udc0b whale\ - -\f0 \uc0\u55357 \u56335 -\f1 \\ud83d\\udc0f ram\ - -\f0 \uc0\u55357 \u56336 -\f1 \\ud83d\\udc10 goat\ - -\f0 \uc0\u55357 \u56339 -\f1 \\ud83d\\udc13 rooster\ - -\f0 \uc0\u55357 \u56341 -\f1 \\ud83d\\udc15 dog\ - -\f0 \uc0\u55357 \u56342 -\f1 \\ud83d\\udc16 pig\ - -\f0 \uc0\u55357 \u56362 -\f1 \\ud83d\\udc2a dromedary camel\ - -\f0 \uc0\u55357 \u56421 -\f1 \\ud83d\\udc65 busts in silhouette\ - -\f0 \uc0\u55357 \u56428 -\f1 \\ud83d\\udc6c two men holding hands\ - -\f0 \uc0\u55357 \u56429 -\f1 \\ud83d\\udc6d two women holding hands\ - -\f0 \uc0\u55357 \u56493 -\f1 \\ud83d\\udcad thought balloon\ - -\f0 \uc0\u55357 \u56502 -\f1 \\ud83d\\udcb6 banknote with euro sign\ - -\f0 \uc0\u55357 \u56503 -\f1 \\ud83d\\udcb7 banknote with pound sign\ - -\f0 \uc0\u55357 \u56556 -\f1 \\ud83d\\udcec open mailbox with raised flag\ - -\f0 \uc0\u55357 \u56557 -\f1 \\ud83d\\udced open mailbox with lowered flag\ - -\f0 \uc0\u55357 \u56559 -\f1 \\ud83d\\udcef postal horn\ - -\f0 \uc0\u55357 \u56565 -\f1 \\ud83d\\udcf5 no mobile phones\ - -\f0 \uc0\u55357 \u56576 -\f1 \\ud83d\\udd00 twisted rightwards arrows\ - -\f0 \uc0\u55357 \u56577 -\f1 \\ud83d\\udd01 clockwise rightwards and leftwards open circle arrows\ - -\f0 \uc0\u55357 \u56578 -\f1 \\ud83d\\udd02 clockwise rightwards and leftwards open circle arrows with circled one overlay\ - -\f0 \uc0\u55357 \u56580 -\f1 \\ud83d\\udd04 anticlockwise downwards and upwards open circle arrows\ - -\f0 \uc0\u55357 \u56581 -\f1 \\ud83d\\udd05 low brightness symbol\ - -\f0 \uc0\u55357 \u56582 -\f1 \\ud83d\\udd06 high brightness symbol\ - -\f0 \uc0\u55357 \u56583 -\f1 \\ud83d\\udd07 speaker with cancellation stroke\ - -\f0 \uc0\u55357 \u56585 -\f1 \\ud83d\\udd09 speaker with one sound wave\ - -\f0 \uc0\u55357 \u56597 -\f1 \\ud83d\\udd15 bell with cancellation stroke\ - -\f0 \uc0\u55357 \u56620 -\f1 \\ud83d\\udd2c microscope\ - -\f0 \uc0\u55357 \u56621 -\f1 \\ud83d\\udd2d telescope\ - -\f0 \uc0\u55357 \u56668 -\f1 \\ud83d\\udd5c clock face one-thirty\ - -\f0 \uc0\u55357 \u56669 -\f1 \\ud83d\\udd5d clock face two-thirty\ - -\f0 \uc0\u55357 \u56670 -\f1 \\ud83d\\udd5e clock face three-thirty\ - -\f0 \uc0\u55357 \u56671 -\f1 \\ud83d\\udd5f clock face four-thirty\ - -\f0 \uc0\u55357 \u56672 -\f1 \\ud83d\\udd60 clock face five-thirty\ - -\f0 \uc0\u55357 \u56673 -\f1 \\ud83d\\udd61 clock face six-thirty\ - -\f0 \uc0\u55357 \u56674 -\f1 \\ud83d\\udd62 clock face seven-thirty\ - -\f0 \uc0\u55357 \u56675 -\f1 \\ud83d\\udd63 clock face eight-thirty\ - -\f0 \uc0\u55357 \u56676 -\f1 \\ud83d\\udd64 clock face nine-thirty\ - -\f0 \uc0\u55357 \u56677 -\f1 \\ud83d\\udd65 clock face ten-thirty\ - -\f0 \uc0\u55357 \u56678 -\f1 \\ud83d\\udd66 clock face eleven-thirty\ - -\f0 \uc0\u55357 \u56679 -\f1 \\ud83d\\udd67 clock face twelve-thirty} \ No newline at end of file diff --git a/assets/favicon.ico b/assets/favicon.ico new file mode 100644 index 00000000..947a3de0 Binary files /dev/null and b/assets/favicon.ico differ diff --git a/src/style/font/fontawesome-webfont.eot b/assets/font/fontawesome-webfont.eot old mode 100755 new mode 100644 similarity index 100% rename from src/style/font/fontawesome-webfont.eot rename to assets/font/fontawesome-webfont.eot diff --git a/src/style/font/fontawesome-webfont.svg b/assets/font/fontawesome-webfont.svg old mode 100755 new mode 100644 similarity index 100% rename from src/style/font/fontawesome-webfont.svg rename to assets/font/fontawesome-webfont.svg diff --git a/src/style/font/fontawesome-webfont.ttf b/assets/font/fontawesome-webfont.ttf old mode 100755 new mode 100644 similarity index 100% rename from src/style/font/fontawesome-webfont.ttf rename to assets/font/fontawesome-webfont.ttf diff --git a/src/style/font/fontawesome-webfont.woff b/assets/font/fontawesome-webfont.woff old mode 100755 new mode 100644 similarity index 100% rename from src/style/font/fontawesome-webfont.woff rename to assets/font/fontawesome-webfont.woff diff --git a/assets/forkme_right_darkblue_121621.png b/assets/forkme_right_darkblue_121621.png deleted file mode 100644 index 146ef8a8..00000000 Binary files a/assets/forkme_right_darkblue_121621.png and /dev/null differ diff --git a/checkgit.sh b/checkgit.sh new file mode 100755 index 00000000..ee29eb4b --- /dev/null +++ b/checkgit.sh @@ -0,0 +1,6 @@ +GIT_STATUS=$(git status --porcelain | wc -l ) +if [[ GIT_STATUS -ne 0 ]]; then + echo "${1:-Source files were modified}" + git status + exit $GIT_STATUS +fi; diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 00000000..c263f85a --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,213 @@ +var { execSync } = require('child_process'); +var { writeFileSync, readdirSync, readFileSync } = require('fs'); + +var glob = require('glob'); +var _ = require('underscore'); + +var { src, dest, series, watch } = require('gulp'); +var log = require('fancy-log'); +var gHash = require('gulp-hash'); +var gClean = require('gulp-clean'); +var concat = require('gulp-concat'); +var cleanCSS = require('gulp-clean-css'); +var gTerser = require('gulp-terser'); +var gJasmine = require('gulp-jasmine'); +var { minify } = require('html-minifier'); +var { SpecReporter } = require('jasmine-spec-reporter'); +var gJshint = require('gulp-jshint'); + +var source = require('vinyl-source-stream'); +var buffer = require('vinyl-buffer'); +var browserify = require('browserify'); +var babelify = require('babelify'); + +_.templateSettings.interpolate = /\{\{(.+?)\}\}/g; +_.templateSettings.escape = /\{\{\{(.*?)\}\}\}/g; +_.templateSettings.evaluate = /\{\{-(.*?)\}\}/g; + +// precompile for speed +var indexFile = readFileSync('src/template.index.html').toString(); +var indexTemplate = _.template(indexFile); + +var compliments = [ + 'Thanks to Hongarc for the modern and amazing gulp workflow!', + 'I hope you all have a great day :)' +]; +var compliment = (done) => { + var index = Math.floor(Math.random() * compliments.length); + + log(compliments[index]); + done(); +}; + +const lintStrings = (done) => { + execSync('node src/js/intl/checkStrings'); + done(); +}; + + +var destDir = './build/'; + +var buildIndex = function(done) { + log('Building index...'); + + // first find the one in here that we want + var buildFiles = readdirSync(destDir); + + var jsRegex = /bundle-[\.\w]+\.js/; + var jsFile = buildFiles.find(function(name) { + return jsRegex.exec(name); + }); + if (!jsFile) { + throw new Error('no hashed min file found!'); + } + log('Found hashed js file: ' + jsFile); + + var styleRegex = /main-[\.\w]+\.css/; + var styleFile = buildFiles.find(function(name) { + return styleRegex.exec(name); + }); + if (!styleFile) { + throw new Error('no hashed css file found!'); + } + log('Found hashed style file: ' + styleFile); + + // output these filenames to our index template + var outputIndex = indexTemplate({ + jsFile, + styleFile, + }); + + if (process.env.NODE_ENV === 'production') { + outputIndex = minify(outputIndex, { + minifyJS: true, + collapseWhitespace: true, + processScripts: ['text/html'], + removeComments: true, + }); + } + writeFileSync('index.html', outputIndex); + done(); +}; + +var getBundle = function() { + return browserify({ + entries: [...glob.sync('src/**/*.js'), ...glob.sync('src/**/*.jsx')], + debug: true, + }) + .transform(babelify, { presets: ['@babel/preset-react'] }) + .bundle() + .pipe(source('bundle.js')) + .pipe(buffer()) + .pipe(gHash()); +}; + +var clean = function () { + return src(destDir, { read: false, allowEmpty: true }) + .pipe(gClean()); +}; + +var jshint = function() { + return src([ + 'gulpfile.js', + '__tests__/', + 'src/' + ]) + .pipe(gJshint()) + .pipe(gJshint.reporter('default')); +}; + +var ifyBuild = function() { + return getBundle() + .pipe(dest(destDir)); +}; + +var miniBuild = function() { + process.env.NODE_ENV = 'production'; + return getBundle() + .pipe(gTerser()) + .pipe(dest(destDir)); +}; + +var style = function() { + var chain = src('src/style/*.css') + .pipe(concat('main.css')); + + if (process.env.NODE_ENV === 'production') { + chain = chain.pipe(cleanCSS()); + } + + return chain.pipe(gHash()) + .pipe(dest(destDir)); +}; + +var jasmine = function() { + return src('__tests__/*.spec.js') + .pipe(gJasmine({ + config: { + verbose: true, + random: false, + }, + reporter: new SpecReporter(), + })); +}; + +var gitAdd = function(done) { + execSync('git add build/'); + done(); +}; + +var gitDeployMergeMaster = function(done) { + execSync('git checkout gh-pages && git merge master -m "merge master"'); + done(); +}; + +var gitDeployPushOrigin = function(done) { + execSync('git commit -am "rebuild for prod"; ' + + 'git push origin gh-pages --force && ' + + 'git branch -f trunk gh-pages && ' + + 'git checkout master' + ); + done(); +}; + +var fastBuild = series(clean, ifyBuild, style, buildIndex, jshint); + +var build = series( + clean, + miniBuild, style, buildIndex, + gitAdd, jasmine, jshint, + lintStrings, compliment +); + +var deploy = series( + clean, + jasmine, + jshint, + gitDeployMergeMaster, + build, + gitDeployPushOrigin, + compliment +); + +var lint = series(jshint, compliment); + +var watching = function() { + return watch([ + 'gulpfile.js', + '__tests__/git.spec.js', + 'src/js/**/*.js', + 'src/js/**/**/*.js', + 'src/levels/**/*.js' + ], series([fastBuild , jasmine, jshint, lintStrings])); +}; + +module.exports = { + default: build, + lint, + fastBuild, + watching, + build, + test: jasmine, + deploy, +}; diff --git a/lib/es5-shim.min.js b/lib/es5-shim.min.js deleted file mode 100644 index de26bb58..00000000 --- a/lib/es5-shim.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * https://github.com/es-shims/es5-shim - * @license es5-shim Copyright 2009-2015 by contributors, MIT License - * see https://github.com/es-shims/es5-shim/blob/v4.1.1/LICENSE - */ -(function(t,e){"use strict";if(typeof define==="function"&&define.amd){define(e)}else if(typeof exports==="object"){module.exports=e()}else{t.returnExports=e()}})(this,function(){var t=Array.prototype;var e=Object.prototype;var r=Function.prototype;var n=String.prototype;var i=Number.prototype;var a=t.slice;var o=t.splice;var u=t.push;var l=t.unshift;var f=r.call;var s=e.toString;var c=Array.isArray||function gt(t){return s.call(t)==="[object Array]"};var p=typeof Symbol==="function"&&typeof Symbol.toStringTag==="symbol";var h;var v=Function.prototype.toString,g=function yt(t){try{v.call(t);return true}catch(e){return false}},y="[object Function]",d="[object GeneratorFunction]";h=function dt(t){if(typeof t!=="function"){return false}if(p){return g(t)}var e=s.call(t);return e===y||e===d};var m;var b=RegExp.prototype.exec,w=function mt(t){try{b.call(t);return true}catch(e){return false}},T="[object RegExp]";m=function bt(t){if(typeof t!=="object"){return false}return p?w(t):s.call(t)===T};var x;var O=String.prototype.valueOf,j=function wt(t){try{O.call(t);return true}catch(e){return false}},S="[object String]";x=function Tt(t){if(typeof t==="string"){return true}if(typeof t!=="object"){return false}return p?j(t):s.call(t)===S};var E=function xt(t){var e=s.call(t);var r=e==="[object Arguments]";if(!r){r=!c(t)&&t!==null&&typeof t==="object"&&typeof t.length==="number"&&t.length>=0&&h(t.callee)}return r};var N=function(t){var e=Object.defineProperty&&function(){try{Object.defineProperty({},"x",{});return true}catch(t){return false}}();var r;if(e){r=function(t,e,r,n){if(!n&&e in t){return}Object.defineProperty(t,e,{configurable:true,enumerable:false,writable:true,value:r})}}else{r=function(t,e,r,n){if(!n&&e in t){return}t[e]=r}}return function n(e,i,a){for(var o in i){if(t.call(i,o)){r(e,o,i[o],a)}}}}(e.hasOwnProperty);function I(t){var e=typeof t;return t===null||e==="undefined"||e==="boolean"||e==="number"||e==="string"}var D={ToInteger:function Ot(t){var e=+t;if(e!==e){e=0}else if(e!==0&&e!==1/0&&e!==-(1/0)){e=(e>0||-1)*Math.floor(Math.abs(e))}return e},ToPrimitive:function jt(t){var e,r,n;if(I(t)){return t}r=t.valueOf;if(h(r)){e=r.call(t);if(I(e)){return e}}n=t.toString;if(h(n)){e=n.call(t);if(I(e)){return e}}throw new TypeError},ToObject:function(t){if(t==null){throw new TypeError("can't convert "+t+" to object")}return Object(t)},ToUint32:function St(t){return t>>>0}};var M=function Et(){};N(r,{bind:function Nt(t){var e=this;if(!h(e)){throw new TypeError("Function.prototype.bind called on incompatible "+e)}var r=a.call(arguments,1);var n;var i=function(){if(this instanceof n){var i=e.apply(this,r.concat(a.call(arguments)));if(Object(i)===i){return i}return this}else{return e.apply(t,r.concat(a.call(arguments)))}};var o=Math.max(0,e.length-r.length);var u=[];for(var l=0;l0&&typeof e!=="number"){r=a.call(arguments);if(r.length<2){r.push(this.length-t)}else{r[1]=D.ToInteger(e)}}return o.apply(this,r)}},!U);var k=[].unshift(0)!==1;N(t,{unshift:function(){l.apply(this,arguments);return this.length}},k);N(Array,{isArray:c});var A=Object("a");var C=A[0]!=="a"||!(0 in A);var P=function Mt(t){var e=true;var r=true;if(t){t.call("foo",function(t,r,n){if(typeof n!=="object"){e=false}});t.call([1],function(){"use strict";r=typeof this==="string"},"x")}return!!t&&e&&r};N(t,{forEach:function Ft(t){var e=D.ToObject(this),r=C&&x(this)?this.split(""):e,n=arguments[1],i=-1,a=r.length>>>0;if(!h(t)){throw new TypeError}while(++i>>0,i=Array(n),a=arguments[1];if(!h(t)){throw new TypeError(t+" is not a function")}for(var o=0;o>>0,i=[],a,o=arguments[1];if(!h(t)){throw new TypeError(t+" is not a function")}for(var u=0;u>>0,i=arguments[1];if(!h(t)){throw new TypeError(t+" is not a function")}for(var a=0;a>>0,i=arguments[1];if(!h(t)){throw new TypeError(t+" is not a function")}for(var a=0;a>>0;if(!h(t)){throw new TypeError(t+" is not a function")}if(!n&&arguments.length===1){throw new TypeError("reduce of empty array with no initial value")}var i=0;var a;if(arguments.length>=2){a=arguments[1]}else{do{if(i in r){a=r[i++];break}if(++i>=n){throw new TypeError("reduce of empty array with no initial value")}}while(true)}for(;i>>0;if(!h(t)){throw new TypeError(t+" is not a function")}if(!n&&arguments.length===1){throw new TypeError("reduceRight of empty array with no initial value")}var i,a=n-1;if(arguments.length>=2){i=arguments[1]}else{do{if(a in r){i=r[a--];break}if(--a<0){throw new TypeError("reduceRight of empty array with no initial value")}}while(true)}if(a<0){return i}do{if(a in r){i=t.call(void 0,i,r[a],a,e)}}while(a--);return i}},!J);var z=Array.prototype.indexOf&&[0,1].indexOf(1,2)!==-1;N(t,{indexOf:function Zt(t){var e=C&&x(this)?this.split(""):D.ToObject(this),r=e.length>>>0;if(!r){return-1}var n=0;if(arguments.length>1){n=D.ToInteger(arguments[1])}n=n>=0?n:Math.max(0,r+n);for(;n>>0;if(!r){return-1}var n=r-1;if(arguments.length>1){n=Math.min(n,D.ToInteger(arguments[1]))}n=n>=0?n:r-Math.abs(n);for(;n>=0;n--){if(n in e&&t===e[n]){return n}}return-1}},$);var B=!{toString:null}.propertyIsEnumerable("toString"),G=function(){}.propertyIsEnumerable("prototype"),H=!F("x","0"),L=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],X=L.length;N(Object,{keys:function zt(t){var e=h(t),r=E(t),n=t!==null&&typeof t==="object",i=n&&x(t);if(!n&&!e&&!r){throw new TypeError("Object.keys called on a non-object")}var a=[];var o=G&&e;if(i&&H||r){for(var u=0;u9999?"+":"")+("00000"+Math.abs(n)).slice(0<=n&&n<=9999?-4:-6);e=t.length;while(e--){r=t[e];if(r<10){t[e]="0"+r}}return n+"-"+t.slice(0,2).join("-")+"T"+t.slice(2).join(":")+"."+("000"+this.getUTCMilliseconds()).slice(-3)+"Z"}},V);var W=function(){try{return Date.prototype.toJSON&&new Date(NaN).toJSON()===null&&new Date(K).toJSON().indexOf(Q)!==-1&&Date.prototype.toJSON.call({toISOString:function(){return true}})}catch(t){return false}}();if(!W){Date.prototype.toJSON=function Gt(t){var e=Object(this);var r=D.ToPrimitive(e);if(typeof r==="number"&&!isFinite(r)){return null}var n=e.toISOString;if(!h(n)){throw new TypeError("toISOString property is not callable")}return n.call(e)}}var _=Date.parse("+033658-09-27T01:46:40.000Z")===1e15;var tt=!isNaN(Date.parse("2012-04-04T24:00:00.500Z"))||!isNaN(Date.parse("2012-11-31T23:59:59.000Z"));var et=isNaN(Date.parse("2000-01-01T00:00:00.000Z"));if(!Date.parse||et||tt||!_){Date=function(t){function e(r,n,i,a,o,u,l){var f=arguments.length;if(this instanceof t){var s=f===1&&String(r)===r?new t(e.parse(r)):f>=7?new t(r,n,i,a,o,u,l):f>=6?new t(r,n,i,a,o,u):f>=5?new t(r,n,i,a,o):f>=4?new t(r,n,i,a):f>=3?new t(r,n,i):f>=2?new t(r,n):f>=1?new t(r):new t;N(s,{constructor:e},true);return s}return t.apply(this,arguments)}var r=new RegExp("^"+"(\\d{4}|[+-]\\d{6})"+"(?:-(\\d{2})"+"(?:-(\\d{2})"+"(?:"+"T(\\d{2})"+":(\\d{2})"+"(?:"+":(\\d{2})"+"(?:(\\.\\d{1,}))?"+")?"+"("+"Z|"+"(?:"+"([-+])"+"(\\d{2})"+":(\\d{2})"+")"+")?)?)?)?"+"$");var n=[0,31,59,90,120,151,181,212,243,273,304,334,365];function i(t,e){var r=e>1?1:0;return n[e]+Math.floor((t-1969+r)/4)-Math.floor((t-1901+r)/100)+Math.floor((t-1601+r)/400)+365*(t-1970)}function a(e){return Number(new t(1970,0,1,0,0,0,e))}for(var o in t){e[o]=t[o]}e.now=t.now;e.UTC=t.UTC;e.prototype=t.prototype;e.prototype.constructor=e;e.parse=function u(e){var n=r.exec(e);if(n){var o=Number(n[1]),u=Number(n[2]||1)-1,l=Number(n[3]||1)-1,f=Number(n[4]||0),s=Number(n[5]||0),c=Number(n[6]||0),p=Math.floor(Number(n[7]||0)*1e3),h=Boolean(n[4]&&!n[8]),v=n[9]==="-"?1:-1,g=Number(n[10]||0),y=Number(n[11]||0),d;if(f<(s>0||c>0||p>0?24:25)&&s<60&&c<60&&p<1e3&&u>-1&&u<12&&g<24&&y<60&&l>-1&&l=0){r+=nt.data[e];nt.data[e]=Math.floor(r/t);r=r%t*nt.base}},numToString:function Yt(){var t=nt.size;var e="";while(--t>=0){if(e!==""||t===0||nt.data[t]!==0){var r=String(nt.data[t]);if(e===""){e=r}else{e+="0000000".slice(0,7-r.length)+r}}}return e},pow:function qt(t,e,r){return e===0?r:e%2===1?qt(t,e-1,r*t):qt(t*t,e/2,r)},log:function Kt(t){var e=0;var r=t;while(r>=4096){e+=12;r/=4096}while(r>=2){e+=1;r/=2}return e}};N(i,{toFixed:function Qt(t){var e,r,n,i,a,o,u,l;e=Number(t);e=e!==e?0:Math.floor(e);if(e<0||e>20){throw new RangeError("Number.toFixed called with invalid number of decimals")}r=Number(this);if(r!==r){return"NaN"}if(r<=-1e21||r>=1e21){return String(r)}n="";if(r<0){n="-";r=-r}i="0";if(r>1e-21){a=nt.log(r*nt.pow(2,69,1))-69;o=a<0?r*nt.pow(2,-a,1):r/nt.pow(2,a,1);o*=4503599627370496;a=52-a;if(a>0){nt.multiply(0,o);u=e;while(u>=7){nt.multiply(1e7,0);u-=7}nt.multiply(nt.pow(10,u,1),0);u=a-1;while(u>=23){nt.divide(1<<23);u-=23}nt.divide(1<0){l=i.length;if(l<=e){i=n+"0.0000000000000000000".slice(0,e-l+2)+i}else{i=n+i.slice(0,l-e)+"."+i.slice(l-e)}}else{i=n+i}return i}},rt);var it=n.split;if("ab".split(/(?:ab)*/).length!==2||".".split(/(.?)(.?)/).length!==4||"tesst".split(/(s)*/)[1]==="t"||"test".split(/(?:)/,-1).length!==4||"".split(/.?/).length||".".split(/()()/).length>1){(function(){var t=typeof/()??/.exec("")[1]==="undefined";n.split=function(e,r){var n=this;if(typeof e==="undefined"&&r===0){return[]}if(!m(e)){return it.call(this,e,r)}var i=[];var a=(e.ignoreCase?"i":"")+(e.multiline?"m":"")+(e.extended?"x":"")+(e.sticky?"y":""),o=0,l,f,s,c;var p=new RegExp(e.source,a+"g");n+="";if(!t){l=new RegExp("^"+p.source+"$(?!\\s)",a)}var h=typeof r==="undefined"?-1>>>0:D.ToUint32(r);f=p.exec(n);while(f){s=f.index+f[0].length;if(s>o){i.push(n.slice(o,f.index));if(!t&&f.length>1){f[0].replace(l,function(){for(var t=1;t1&&f.index=h){break}}if(p.lastIndex===f.index){p.lastIndex++}f=p.exec(n)}if(o===n.length){if(c||!p.test("")){i.push("")}}else{i.push(n.slice(o))}return i.length>h?i.slice(0,h):i}})()}else if("0".split(void 0,0).length){n.split=function Vt(t,e){if(typeof t==="undefined"&&e===0){return[]}return it.call(this,t,e)}}var at=n.replace;var ot=function(){var t=[];"x".replace(/x(.)?/g,function(e,r){t.push(r)});return t.length===1&&typeof t[0]==="undefined"}();if(!ot){n.replace=function Wt(t,e){var r=h(e);var n=m(t)&&/\)[*?]/.test(t.source);if(!r||!n){return at.call(this,t,e)}else{var i=function(r){var n=arguments.length;var i=t.lastIndex;t.lastIndex=0;var a=t.exec(r)||[];t.lastIndex=i;a.push(arguments[n-2],arguments[n-1]);return e.apply(this,a)};return at.call(this,t,i)}}}var ut=n.substr;var lt="".substr&&"0b".substr(-1)!=="b";N(n,{substr:function _t(t,e){var r=t;if(t<0){r=Math.max(this.length+t,0)}return ut.call(this,r,e)}},lt);var ft=" \n \f\r \xa0\u1680\u180e\u2000\u2001\u2002\u2003"+"\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028"+"\u2029\ufeff";var st="\u200b";var ct="["+ft+"]";var pt=new RegExp("^"+ct+ct+"*");var ht=new RegExp(ct+ct+"*$");var vt=n.trim&&(ft.trim()||!st.trim());N(n,{trim:function te(){if(typeof this==="undefined"||this===null){throw new TypeError("can't convert "+this+" to object")}return String(this).replace(pt,"").replace(ht,"")}},vt);if(parseInt(ft+"08")!==8||parseInt(ft+"0x16")!==22){parseInt=function(t){var e=/^0[xX]/;return function r(n,i){var a=String(n).trim();var o=Number(i)||(e.test(a)?16:10);return t(a,o)}}(parseInt)}}); -//# sourceMappingURL=es5-shim.map \ No newline at end of file diff --git a/lib/jquery-1.8.0.min.js b/lib/jquery-1.8.0.min.js deleted file mode 100644 index f121291c..00000000 --- a/lib/jquery-1.8.0.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! jQuery v@1.8.0 jquery.com | jquery.org/license */ -(function(a,b){function G(a){var b=F[a]={};return p.each(a.split(s),function(a,c){b[c]=!0}),b}function J(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(I,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:+d+""===d?+d:H.test(d)?p.parseJSON(d):d}catch(f){}p.data(a,c,d)}else d=b}return d}function K(a){var b;for(b in a){if(b==="data"&&p.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function ba(){return!1}function bb(){return!0}function bh(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function bi(a,b){do a=a[b];while(a&&a.nodeType!==1);return a}function bj(a,b,c){b=b||0;if(p.isFunction(b))return p.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return p.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=p.grep(a,function(a){return a.nodeType===1});if(be.test(b))return p.filter(b,d,!c);b=p.filter(b,d)}return p.grep(a,function(a,d){return p.inArray(a,b)>=0===c})}function bk(a){var b=bl.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function bC(a,b){return a.getElementsByTagName(b)[0]||a.appendChild(a.ownerDocument.createElement(b))}function bD(a,b){if(b.nodeType!==1||!p.hasData(a))return;var c,d,e,f=p._data(a),g=p._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;d").appendTo(e.body),c=b.css("display");b.remove();if(c==="none"||c===""){bI=e.body.appendChild(bI||p.extend(e.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!bJ||!bI.createElement)bJ=(bI.contentWindow||bI.contentDocument).document,bJ.write(""),bJ.close();b=bJ.body.appendChild(bJ.createElement(a)),c=bH(b,"display"),e.body.removeChild(bI)}return bR[a]=c,c}function ch(a,b,c,d){var e;if(p.isArray(b))p.each(b,function(b,e){c||cd.test(a)?d(a,e):ch(a+"["+(typeof e=="object"?b:"")+"]",e,c,d)});else if(!c&&p.type(b)==="object")for(e in b)ch(a+"["+e+"]",b[e],c,d);else d(a,b)}function cy(a){return function(b,c){typeof b!="string"&&(c=b,b="*");var d,e,f,g=b.toLowerCase().split(s),h=0,i=g.length;if(p.isFunction(c))for(;h)[^>]*$|#([\w\-]*)$)/,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,y=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,z=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,A=/^-ms-/,B=/-([\da-z])/gi,C=function(a,b){return(b+"").toUpperCase()},D=function(){e.addEventListener?(e.removeEventListener("DOMContentLoaded",D,!1),p.ready()):e.readyState==="complete"&&(e.detachEvent("onreadystatechange",D),p.ready())},E={};p.fn=p.prototype={constructor:p,init:function(a,c,d){var f,g,h,i;if(!a)return this;if(a.nodeType)return this.context=this[0]=a,this.length=1,this;if(typeof a=="string"){a.charAt(0)==="<"&&a.charAt(a.length-1)===">"&&a.length>=3?f=[null,a,null]:f=u.exec(a);if(f&&(f[1]||!c)){if(f[1])return c=c instanceof p?c[0]:c,i=c&&c.nodeType?c.ownerDocument||c:e,a=p.parseHTML(f[1],i,!0),v.test(f[1])&&p.isPlainObject(c)&&this.attr.call(a,c,!0),p.merge(this,a);g=e.getElementById(f[2]);if(g&&g.parentNode){if(g.id!==f[2])return d.find(a);this.length=1,this[0]=g}return this.context=e,this.selector=a,this}return!c||c.jquery?(c||d).find(a):this.constructor(c).find(a)}return p.isFunction(a)?d.ready(a):(a.selector!==b&&(this.selector=a.selector,this.context=a.context),p.makeArray(a,this))},selector:"",jquery:"1.8.0",length:0,size:function(){return this.length},toArray:function(){return k.call(this)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=p.merge(this.constructor(),a);return d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")"),d},each:function(a,b){return p.each(this,a,b)},ready:function(a){return p.ready.promise().done(a),this},eq:function(a){return a=+a,a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(k.apply(this,arguments),"slice",k.call(arguments).join(","))},map:function(a){return this.pushStack(p.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:j,sort:[].sort,splice:[].splice},p.fn.init.prototype=p.fn,p.extend=p.fn.extend=function(){var a,c,d,e,f,g,h=arguments[0]||{},i=1,j=arguments.length,k=!1;typeof h=="boolean"&&(k=h,h=arguments[1]||{},i=2),typeof h!="object"&&!p.isFunction(h)&&(h={}),j===i&&(h=this,--i);for(;i0)return;d.resolveWith(e,[p]),p.fn.trigger&&p(e).trigger("ready").off("ready")},isFunction:function(a){return p.type(a)==="function"},isArray:Array.isArray||function(a){return p.type(a)==="array"},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):E[m.call(a)]||"object"},isPlainObject:function(a){if(!a||p.type(a)!=="object"||a.nodeType||p.isWindow(a))return!1;try{if(a.constructor&&!n.call(a,"constructor")&&!n.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||n.call(a,d)},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},error:function(a){throw new Error(a)},parseHTML:function(a,b,c){var d;return!a||typeof a!="string"?null:(typeof b=="boolean"&&(c=b,b=0),b=b||e,(d=v.exec(a))?[b.createElement(d[1])]:(d=p.buildFragment([a],b,c?null:[]),p.merge([],(d.cacheable?p.clone(d.fragment):d.fragment).childNodes)))},parseJSON:function(b){if(!b||typeof b!="string")return null;b=p.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(w.test(b.replace(y,"@").replace(z,"]").replace(x,"")))return(new Function("return "+b))();p.error("Invalid JSON: "+b)},parseXML:function(c){var d,e;if(!c||typeof c!="string")return null;try{a.DOMParser?(e=new DOMParser,d=e.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(f){d=b}return(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&p.error("Invalid XML: "+c),d},noop:function(){},globalEval:function(b){b&&r.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(A,"ms-").replace(B,C)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var e,f=0,g=a.length,h=g===b||p.isFunction(a);if(d){if(h){for(e in a)if(c.apply(a[e],d)===!1)break}else for(;f0&&a[0]&&a[i-1]||i===0||p.isArray(a));if(j)for(;h-1)i.splice(c,1),e&&(c<=g&&g--,c<=h&&h--)}),this},has:function(a){return p.inArray(a,i)>-1},empty:function(){return i=[],this},disable:function(){return i=j=c=b,this},disabled:function(){return!i},lock:function(){return j=b,c||l.disable(),this},locked:function(){return!j},fireWith:function(a,b){return b=b||[],b=[a,b.slice?b.slice():b],i&&(!d||j)&&(e?j.push(b):k(b)),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!d}};return l},p.extend({Deferred:function(a){var b=[["resolve","done",p.Callbacks("once memory"),"resolved"],["reject","fail",p.Callbacks("once memory"),"rejected"],["notify","progress",p.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return p.Deferred(function(c){p.each(b,function(b,d){var f=d[0],g=a[b];e[d[1]](p.isFunction(g)?function(){var a=g.apply(this,arguments);a&&p.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f+"With"](this===e?c:this,[a])}:c[f])}),a=null}).promise()},promise:function(a){return typeof a=="object"?p.extend(a,d):d}},e={};return d.pipe=d.then,p.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[a^1][2].disable,b[2][2].lock),e[f[0]]=g.fire,e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=k.call(arguments),d=c.length,e=d!==1||a&&p.isFunction(a.promise)?d:0,f=e===1?a:p.Deferred(),g=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?k.call(arguments):d,c===h?f.notifyWith(b,c):--e||f.resolveWith(b,c)}},h,i,j;if(d>1){h=new Array(d),i=new Array(d),j=new Array(d);for(;b
a",c=n.getElementsByTagName("*"),d=n.getElementsByTagName("a")[0],d.style.cssText="top:1px;float:left;opacity:.5";if(!c||!c.length||!d)return{};f=e.createElement("select"),g=f.appendChild(e.createElement("option")),h=n.getElementsByTagName("input")[0],b={leadingWhitespace:n.firstChild.nodeType===3,tbody:!n.getElementsByTagName("tbody").length,htmlSerialize:!!n.getElementsByTagName("link").length,style:/top/.test(d.getAttribute("style")),hrefNormalized:d.getAttribute("href")==="/a",opacity:/^0.5/.test(d.style.opacity),cssFloat:!!d.style.cssFloat,checkOn:h.value==="on",optSelected:g.selected,getSetAttribute:n.className!=="t",enctype:!!e.createElement("form").enctype,html5Clone:e.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",boxModel:e.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},h.checked=!0,b.noCloneChecked=h.cloneNode(!0).checked,f.disabled=!0,b.optDisabled=!g.disabled;try{delete n.test}catch(o){b.deleteExpando=!1}!n.addEventListener&&n.attachEvent&&n.fireEvent&&(n.attachEvent("onclick",m=function(){b.noCloneEvent=!1}),n.cloneNode(!0).fireEvent("onclick"),n.detachEvent("onclick",m)),h=e.createElement("input"),h.value="t",h.setAttribute("type","radio"),b.radioValue=h.value==="t",h.setAttribute("checked","checked"),h.setAttribute("name","t"),n.appendChild(h),i=e.createDocumentFragment(),i.appendChild(n.lastChild),b.checkClone=i.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=h.checked,i.removeChild(h),i.appendChild(n);if(n.attachEvent)for(k in{submit:!0,change:!0,focusin:!0})j="on"+k,l=j in n,l||(n.setAttribute(j,"return;"),l=typeof n[j]=="function"),b[k+"Bubbles"]=l;return p(function(){var c,d,f,g,h="padding:0;margin:0;border:0;display:block;overflow:hidden;",i=e.getElementsByTagName("body")[0];if(!i)return;c=e.createElement("div"),c.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",i.insertBefore(c,i.firstChild),d=e.createElement("div"),c.appendChild(d),d.innerHTML="
t
",f=d.getElementsByTagName("td"),f[0].style.cssText="padding:0;margin:0;border:0;display:none",l=f[0].offsetHeight===0,f[0].style.display="",f[1].style.display="none",b.reliableHiddenOffsets=l&&f[0].offsetHeight===0,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",b.boxSizing=d.offsetWidth===4,b.doesNotIncludeMarginInBodyOffset=i.offsetTop!==1,a.getComputedStyle&&(b.pixelPosition=(a.getComputedStyle(d,null)||{}).top!=="1%",b.boxSizingReliable=(a.getComputedStyle(d,null)||{width:"4px"}).width==="4px",g=e.createElement("div"),g.style.cssText=d.style.cssText=h,g.style.marginRight=g.style.width="0",d.style.width="1px",d.appendChild(g),b.reliableMarginRight=!parseFloat((a.getComputedStyle(g,null)||{}).marginRight)),typeof d.style.zoom!="undefined"&&(d.innerHTML="",d.style.cssText=h+"width:1px;padding:1px;display:inline;zoom:1",b.inlineBlockNeedsLayout=d.offsetWidth===3,d.style.display="block",d.style.overflow="visible",d.innerHTML="
",d.firstChild.style.width="5px",b.shrinkWrapBlocks=d.offsetWidth!==3,c.style.zoom=1),i.removeChild(c),c=d=f=g=null}),i.removeChild(n),c=d=f=g=h=i=n=null,b}();var H=/^(?:\{.*\}|\[.*\])$/,I=/([A-Z])/g;p.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(p.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){return a=a.nodeType?p.cache[a[p.expando]]:a[p.expando],!!a&&!K(a)},data:function(a,c,d,e){if(!p.acceptData(a))return;var f,g,h=p.expando,i=typeof c=="string",j=a.nodeType,k=j?p.cache:a,l=j?a[h]:a[h]&&h;if((!l||!k[l]||!e&&!k[l].data)&&i&&d===b)return;l||(j?a[h]=l=p.deletedIds.pop()||++p.uuid:l=h),k[l]||(k[l]={},j||(k[l].toJSON=p.noop));if(typeof c=="object"||typeof c=="function")e?k[l]=p.extend(k[l],c):k[l].data=p.extend(k[l].data,c);return f=k[l],e||(f.data||(f.data={}),f=f.data),d!==b&&(f[p.camelCase(c)]=d),i?(g=f[c],g==null&&(g=f[p.camelCase(c)])):g=f,g},removeData:function(a,b,c){if(!p.acceptData(a))return;var d,e,f,g=a.nodeType,h=g?p.cache:a,i=g?a[p.expando]:p.expando;if(!h[i])return;if(b){d=c?h[i]:h[i].data;if(d){p.isArray(b)||(b in d?b=[b]:(b=p.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,f=b.length;e1,null,!1))},removeData:function(a){return this.each(function(){p.removeData(this,a)})}}),p.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=p._data(a,b),c&&(!d||p.isArray(c)?d=p._data(a,b,p.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=p.queue(a,b),d=c.shift(),e=p._queueHooks(a,b),f=function(){p.dequeue(a,b)};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),delete e.stop,d.call(a,f,e)),!c.length&&e&&e.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return p._data(a,c)||p._data(a,c,{empty:p.Callbacks("once memory").add(function(){p.removeData(a,b+"queue",!0),p.removeData(a,c,!0)})})}}),p.fn.extend({queue:function(a,c){var d=2;return typeof a!="string"&&(c=a,a="fx",d--),arguments.length1)},removeAttr:function(a){return this.each(function(){p.removeAttr(this,a)})},prop:function(a,b){return p.access(this,p.prop,a,b,arguments.length>1)},removeProp:function(a){return a=p.propFix[a]||a,this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,f,g,h;if(p.isFunction(a))return this.each(function(b){p(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(s);for(c=0,d=this.length;c-1)d=d.replace(" "+c[f]+" "," ");e.className=a?p.trim(d):""}}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";return p.isFunction(a)?this.each(function(c){p(this).toggleClass(a.call(this,c,this.className,b),b)}):this.each(function(){if(c==="string"){var e,f=0,g=p(this),h=b,i=a.split(s);while(e=i[f++])h=d?h:!g.hasClass(e),g[h?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&p._data(this,"__className__",this.className),this.className=this.className||a===!1?"":p._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c-1)return!0;return!1},val:function(a){var c,d,e,f=this[0];if(!arguments.length){if(f)return c=p.valHooks[f.type]||p.valHooks[f.nodeName.toLowerCase()],c&&"get"in c&&(d=c.get(f,"value"))!==b?d:(d=f.value,typeof d=="string"?d.replace(P,""):d==null?"":d);return}return e=p.isFunction(a),this.each(function(d){var f,g=p(this);if(this.nodeType!==1)return;e?f=a.call(this,d,g.val()):f=a,f==null?f="":typeof f=="number"?f+="":p.isArray(f)&&(f=p.map(f,function(a){return a==null?"":a+""})),c=p.valHooks[this.type]||p.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,f,"value")===b)this.value=f})}}),p.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,f=a.selectedIndex,g=[],h=a.options,i=a.type==="select-one";if(f<0)return null;c=i?f:0,d=i?f+1:h.length;for(;c=0}),c.length||(a.selectedIndex=-1),c}}},attrFn:{},attr:function(a,c,d,e){var f,g,h,i=a.nodeType;if(!a||i===3||i===8||i===2)return;if(e&&p.isFunction(p.fn[c]))return p(a)[c](d);if(typeof a.getAttribute=="undefined")return p.prop(a,c,d);h=i!==1||!p.isXMLDoc(a),h&&(c=c.toLowerCase(),g=p.attrHooks[c]||(T.test(c)?M:L));if(d!==b){if(d===null){p.removeAttr(a,c);return}return g&&"set"in g&&h&&(f=g.set(a,d,c))!==b?f:(a.setAttribute(c,""+d),d)}return g&&"get"in g&&h&&(f=g.get(a,c))!==null?f:(f=a.getAttribute(c),f===null?b:f)},removeAttr:function(a,b){var c,d,e,f,g=0;if(b&&a.nodeType===1){d=b.split(s);for(;g=0}})});var V=/^(?:textarea|input|select)$/i,W=/^([^\.]*|)(?:\.(.+)|)$/,X=/(?:^|\s)hover(\.\S+|)\b/,Y=/^key/,Z=/^(?:mouse|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=function(a){return p.event.special.hover?a:a.replace(X,"mouseenter$1 mouseleave$1")};p.event={add:function(a,c,d,e,f){var g,h,i,j,k,l,m,n,o,q,r;if(a.nodeType===3||a.nodeType===8||!c||!d||!(g=p._data(a)))return;d.handler&&(o=d,d=o.handler,f=o.selector),d.guid||(d.guid=p.guid++),i=g.events,i||(g.events=i={}),h=g.handle,h||(g.handle=h=function(a){return typeof p!="undefined"&&(!a||p.event.triggered!==a.type)?p.event.dispatch.apply(h.elem,arguments):b},h.elem=a),c=p.trim(_(c)).split(" ");for(j=0;j=0&&(s=s.slice(0,-1),i=!0),s.indexOf(".")>=0&&(t=s.split("."),s=t.shift(),t.sort());if((!f||p.event.customEvent[s])&&!p.event.global[s])return;c=typeof c=="object"?c[p.expando]?c:new p.Event(s,c):new p.Event(s),c.type=s,c.isTrigger=!0,c.exclusive=i,c.namespace=t.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+t.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,m=s.indexOf(":")<0?"on"+s:"";if(!f){h=p.cache;for(j in h)h[j].events&&h[j].events[s]&&p.event.trigger(c,d,h[j].handle.elem,!0);return}c.result=b,c.target||(c.target=f),d=d!=null?p.makeArray(d):[],d.unshift(c),n=p.event.special[s]||{};if(n.trigger&&n.trigger.apply(f,d)===!1)return;q=[[f,n.bindType||s]];if(!g&&!n.noBubble&&!p.isWindow(f)){r=n.delegateType||s,k=$.test(r+s)?f:f.parentNode;for(l=f;k;k=k.parentNode)q.push([k,r]),l=k;l===(f.ownerDocument||e)&&q.push([l.defaultView||l.parentWindow||a,r])}for(j=0;jq&&u.push({elem:this,matches:o.slice(q)});for(d=0;d0?this.on(b,null,a,c):this.trigger(b)},Y.test(b)&&(p.event.fixHooks[b]=p.event.keyHooks),Z.test(b)&&(p.event.fixHooks[b]=p.event.mouseHooks)}),function(a,b){function bd(a,b,c,d){var e=0,f=b.length;for(;e0?h(g,c,f):[]}function bf(a,c,d,e,f){var g,h,i,j,k,l,m,n,p=0,q=f.length,s=L.POS,t=new RegExp("^"+s.source+"(?!"+r+")","i"),u=function(){var a=1,c=arguments.length-2;for(;ai){m=a.slice(i,g.index),i=n,l=[c],B.test(m)&&(k&&(l=k),k=e);if(h=H.test(m))m=m.slice(0,-5).replace(B,"$&*");g.length>1&&g[0].replace(t,u),k=be(m,g[1],g[2],l,k,h)}}k?(j=j.concat(k),(m=a.slice(i))&&m!==")"?B.test(m)?bd(m,j,d,e):Z(m,c,d,e?e.concat(k):k):o.apply(d,j)):Z(a,c,d,e)}return q===1?d:Z.uniqueSort(d)}function bg(a,b,c){var d,e,f,g=[],i=0,j=D.exec(a),k=!j.pop()&&!j.pop(),l=k&&a.match(C)||[""],m=$.preFilter,n=$.filter,o=!c&&b!==h;for(;(e=l[i])!=null&&k;i++){g.push(d=[]),o&&(e=" "+e);while(e){k=!1;if(j=B.exec(e))e=e.slice(j[0].length),k=d.push({part:j.pop().replace(A," "),captures:j});for(f in n)(j=L[f].exec(e))&&(!m[f]||(j=m[f](j,b,c)))&&(e=e.slice(j.shift().length),k=d.push({part:f,captures:j}));if(!k)break}}return k||Z.error(a),g}function bh(a,b,e){var f=b.dir,g=m++;return a||(a=function(a){return a===e}),b.first?function(b,c){while(b=b[f])if(b.nodeType===1)return a(b,c)&&b}:function(b,e){var h,i=g+"."+d,j=i+"."+c;while(b=b[f])if(b.nodeType===1){if((h=b[q])===j)return b.sizset;if(typeof h=="string"&&h.indexOf(i)===0){if(b.sizset)return b}else{b[q]=j;if(a(b,e))return b.sizset=!0,b;b.sizset=!1}}}}function bi(a,b){return a?function(c,d){var e=b(c,d);return e&&a(e===!0?c:e,d)}:b}function bj(a,b,c){var d,e,f=0;for(;d=a[f];f++)$.relative[d.part]?e=bh(e,$.relative[d.part],b):(d.captures.push(b,c),e=bi(e,$.filter[d.part].apply(null,d.captures)));return e}function bk(a){return function(b,c){var d,e=0;for(;d=a[e];e++)if(d(b,c))return!0;return!1}}var c,d,e,f,g,h=a.document,i=h.documentElement,j="undefined",k=!1,l=!0,m=0,n=[].slice,o=[].push,q=("sizcache"+Math.random()).replace(".",""),r="[\\x20\\t\\r\\n\\f]",s="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",t=s.replace("w","w#"),u="([*^$|!~]?=)",v="\\["+r+"*("+s+")"+r+"*(?:"+u+r+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+t+")|)|)"+r+"*\\]",w=":("+s+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|((?:[^,]|\\\\,|(?:,(?=[^\\[]*\\]))|(?:,(?=[^\\(]*\\))))*))\\)|)",x=":(nth|eq|gt|lt|first|last|even|odd)(?:\\((\\d*)\\)|)(?=[^-]|$)",y=r+"*([\\x20\\t\\r\\n\\f>+~])"+r+"*",z="(?=[^\\x20\\t\\r\\n\\f])(?:\\\\.|"+v+"|"+w.replace(2,7)+"|[^\\\\(),])+",A=new RegExp("^"+r+"+|((?:^|[^\\\\])(?:\\\\.)*)"+r+"+$","g"),B=new RegExp("^"+y),C=new RegExp(z+"?(?="+r+"*,|$)","g"),D=new RegExp("^(?:(?!,)(?:(?:^|,)"+r+"*"+z+")*?|"+r+"*(.*?))(\\)|$)"),E=new RegExp(z.slice(19,-6)+"\\x20\\t\\r\\n\\f>+~])+|"+y,"g"),F=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,G=/[\x20\t\r\n\f]*[+~]/,H=/:not\($/,I=/h\d/i,J=/input|select|textarea|button/i,K=/\\(?!\\)/g,L={ID:new RegExp("^#("+s+")"),CLASS:new RegExp("^\\.("+s+")"),NAME:new RegExp("^\\[name=['\"]?("+s+")['\"]?\\]"),TAG:new RegExp("^("+s.replace("[-","[-\\*")+")"),ATTR:new RegExp("^"+v),PSEUDO:new RegExp("^"+w),CHILD:new RegExp("^:(only|nth|last|first)-child(?:\\("+r+"*(even|odd|(([+-]|)(\\d*)n|)"+r+"*(?:([+-]|)"+r+"*(\\d+)|))"+r+"*\\)|)","i"),POS:new RegExp(x,"ig"),needsContext:new RegExp("^"+r+"*[>+~]|"+x,"i")},M={},N=[],O={},P=[],Q=function(a){return a.sizzleFilter=!0,a},R=function(a){return function(b){return b.nodeName.toLowerCase()==="input"&&b.type===a}},S=function(a){return function(b){var c=b.nodeName.toLowerCase();return(c==="input"||c==="button")&&b.type===a}},T=function(a){var b=!1,c=h.createElement("div");try{b=a(c)}catch(d){}return c=null,b},U=T(function(a){a.innerHTML="";var b=typeof a.lastChild.getAttribute("multiple");return b!=="boolean"&&b!=="string"}),V=T(function(a){a.id=q+0,a.innerHTML="
",i.insertBefore(a,i.firstChild);var b=h.getElementsByName&&h.getElementsByName(q).length===2+h.getElementsByName(q+0).length;return g=!h.getElementById(q),i.removeChild(a),b}),W=T(function(a){return a.appendChild(h.createComment("")),a.getElementsByTagName("*").length===0}),X=T(function(a){return a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!==j&&a.firstChild.getAttribute("href")==="#"}),Y=T(function(a){return a.innerHTML="",!a.getElementsByClassName||a.getElementsByClassName("e").length===0?!1:(a.lastChild.className="e",a.getElementsByClassName("e").length!==1)}),Z=function(a,b,c,d){c=c||[],b=b||h;var e,f,g,i,j=b.nodeType;if(j!==1&&j!==9)return[];if(!a||typeof a!="string")return c;g=ba(b);if(!g&&!d)if(e=F.exec(a))if(i=e[1]){if(j===9){f=b.getElementById(i);if(!f||!f.parentNode)return c;if(f.id===i)return c.push(f),c}else if(b.ownerDocument&&(f=b.ownerDocument.getElementById(i))&&bb(b,f)&&f.id===i)return c.push(f),c}else{if(e[2])return o.apply(c,n.call(b.getElementsByTagName(a),0)),c;if((i=e[3])&&Y&&b.getElementsByClassName)return o.apply(c,n.call(b.getElementsByClassName(i),0)),c}return bm(a,b,c,d,g)},$=Z.selectors={cacheLength:50,match:L,order:["ID","TAG"],attrHandle:{},createPseudo:Q,find:{ID:g?function(a,b,c){if(typeof b.getElementById!==j&&!c){var d=b.getElementById(a);return d&&d.parentNode?[d]:[]}}:function(a,c,d){if(typeof c.getElementById!==j&&!d){var e=c.getElementById(a);return e?e.id===a||typeof e.getAttributeNode!==j&&e.getAttributeNode("id").value===a?[e]:b:[]}},TAG:W?function(a,b){if(typeof b.getElementsByTagName!==j)return b.getElementsByTagName(a)}:function(a,b){var c=b.getElementsByTagName(a);if(a==="*"){var d,e=[],f=0;for(;d=c[f];f++)d.nodeType===1&&e.push(d);return e}return c}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(K,""),a[3]=(a[4]||a[5]||"").replace(K,""),a[2]==="~="&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),a[1]==="nth"?(a[2]||Z.error(a[0]),a[3]=+(a[3]?a[4]+(a[5]||1):2*(a[2]==="even"||a[2]==="odd")),a[4]=+(a[6]+a[7]||a[2]==="odd")):a[2]&&Z.error(a[0]),a},PSEUDO:function(a){var b,c=a[4];return L.CHILD.test(a[0])?null:(c&&(b=D.exec(c))&&b.pop()&&(a[0]=a[0].slice(0,b[0].length-c.length-1),c=b[0].slice(0,-1)),a.splice(2,3,c||a[3]),a)}},filter:{ID:g?function(a){return a=a.replace(K,""),function(b){return b.getAttribute("id")===a}}:function(a){return a=a.replace(K,""),function(b){var c=typeof b.getAttributeNode!==j&&b.getAttributeNode("id");return c&&c.value===a}},TAG:function(a){return a==="*"?function(){return!0}:(a=a.replace(K,"").toLowerCase(),function(b){return b.nodeName&&b.nodeName.toLowerCase()===a})},CLASS:function(a){var b=M[a];return b||(b=M[a]=new RegExp("(^|"+r+")"+a+"("+r+"|$)"),N.push(a),N.length>$.cacheLength&&delete M[N.shift()]),function(a){return b.test(a.className||typeof a.getAttribute!==j&&a.getAttribute("class")||"")}},ATTR:function(a,b,c){return b?function(d){var e=Z.attr(d,a),f=e+"";if(e==null)return b==="!=";switch(b){case"=":return f===c;case"!=":return f!==c;case"^=":return c&&f.indexOf(c)===0;case"*=":return c&&f.indexOf(c)>-1;case"$=":return c&&f.substr(f.length-c.length)===c;case"~=":return(" "+f+" ").indexOf(c)>-1;case"|=":return f===c||f.substr(0,c.length+1)===c+"-"}}:function(b){return Z.attr(b,a)!=null}},CHILD:function(a,b,c,d){if(a==="nth"){var e=m++;return function(a){var b,f,g=0,h=a;if(c===1&&d===0)return!0;b=a.parentNode;if(b&&(b[q]!==e||!a.sizset)){for(h=b.firstChild;h;h=h.nextSibling)if(h.nodeType===1){h.sizset=++g;if(h===a)break}b[q]=e}return f=a.sizset-d,c===0?f===0:f%c===0&&f/c>=0}}return function(b){var c=b;switch(a){case"only":case"first":while(c=c.previousSibling)if(c.nodeType===1)return!1;if(a==="first")return!0;c=b;case"last":while(c=c.nextSibling)if(c.nodeType===1)return!1;return!0}}},PSEUDO:function(a,b,c,d){var e=$.pseudos[a]||$.pseudos[a.toLowerCase()];return e||Z.error("unsupported pseudo: "+a),e.sizzleFilter?e(b,c,d):e}},pseudos:{not:Q(function(a,b,c){var d=bl(a.replace(A,"$1"),b,c);return function(a){return!d(a)}}),enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&!!a.checked||b==="option"&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},parent:function(a){return!$.pseudos.empty(a)},empty:function(a){var b;a=a.firstChild;while(a){if(a.nodeName>"@"||(b=a.nodeType)===3||b===4)return!1;a=a.nextSibling}return!0},contains:Q(function(a){return function(b){return(b.textContent||b.innerText||bc(b)).indexOf(a)>-1}}),has:Q(function(a){return function(b){return Z(a,b).length>0}}),header:function(a){return I.test(a.nodeName)},text:function(a){var b,c;return a.nodeName.toLowerCase()==="input"&&(b=a.type)==="text"&&((c=a.getAttribute("type"))==null||c.toLowerCase()===b)},radio:R("radio"),checkbox:R("checkbox"),file:R("file"),password:R("password"),image:R("image"),submit:S("submit"),reset:S("reset"),button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&a.type==="button"||b==="button"},input:function(a){return J.test(a.nodeName)},focus:function(a){var b=a.ownerDocument;return a===b.activeElement&&(!b.hasFocus||b.hasFocus())&&(!!a.type||!!a.href)},active:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b,c){return c?a.slice(1):[a[0]]},last:function(a,b,c){var d=a.pop();return c?a:[d]},even:function(a,b,c){var d=[],e=c?1:0,f=a.length;for(;e$.cacheLength&&delete O[P.shift()],g};Z.matches=function(a,b){return Z(a,null,null,b)},Z.matchesSelector=function(a,b){return Z(b,null,null,[a]).length>0};var bm=function(a,b,e,f,g){a=a.replace(A,"$1");var h,i,j,k,l,m,p,q,r,s=a.match(C),t=a.match(E),u=b.nodeType;if(L.POS.test(a))return bf(a,b,e,f,s);if(f)h=n.call(f,0);else if(s&&s.length===1){if(t.length>1&&u===9&&!g&&(s=L.ID.exec(t[0]))){b=$.find.ID(s[1],b,g)[0];if(!b)return e;a=a.slice(t.shift().length)}q=(s=G.exec(t[0]))&&!s.index&&b.parentNode||b,r=t.pop(),m=r.split(":not")[0];for(j=0,k=$.order.length;j",a.querySelectorAll("[selected]").length||e.push("\\["+r+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),a.querySelectorAll(":checked").length||e.push(":checked")}),T(function(a){a.innerHTML="

",a.querySelectorAll("[test^='']").length&&e.push("[*^$]="+r+"*(?:\"\"|'')"),a.innerHTML="",a.querySelectorAll(":enabled").length||e.push(":enabled",":disabled")}),e=e.length&&new RegExp(e.join("|")),bm=function(a,d,f,g,h){if(!g&&!h&&(!e||!e.test(a)))if(d.nodeType===9)try{return o.apply(f,n.call(d.querySelectorAll(a),0)),f}catch(i){}else if(d.nodeType===1&&d.nodeName.toLowerCase()!=="object"){var j=d.getAttribute("id"),k=j||q,l=G.test(a)&&d.parentNode||d;j?k=k.replace(c,"\\$&"):d.setAttribute("id",k);try{return o.apply(f,n.call(l.querySelectorAll(a.replace(C,"[id='"+k+"'] $&")),0)),f}catch(i){}finally{j||d.removeAttribute("id")}}return b(a,d,f,g,h)},g&&(T(function(b){a=g.call(b,"div");try{g.call(b,"[test!='']:sizzle"),f.push($.match.PSEUDO)}catch(c){}}),f=new RegExp(f.join("|")),Z.matchesSelector=function(b,c){c=c.replace(d,"='$1']");if(!ba(b)&&!f.test(c)&&(!e||!e.test(c)))try{var h=g.call(b,c);if(h||a||b.document&&b.document.nodeType!==11)return h}catch(i){}return Z(c,null,null,[b]).length>0})}(),Z.attr=p.attr,p.find=Z,p.expr=Z.selectors,p.expr[":"]=p.expr.pseudos,p.unique=Z.uniqueSort,p.text=Z.getText,p.isXMLDoc=Z.isXML,p.contains=Z.contains}(a);var bc=/Until$/,bd=/^(?:parents|prev(?:Until|All))/,be=/^.[^:#\[\.,]*$/,bf=p.expr.match.needsContext,bg={children:!0,contents:!0,next:!0,prev:!0};p.fn.extend({find:function(a){var b,c,d,e,f,g,h=this;if(typeof a!="string")return p(a).filter(function(){for(b=0,c=h.length;b0)for(e=d;e=0:p.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c,d=0,e=this.length,f=[],g=bf.test(a)||typeof a!="string"?p(a,b||this.context):0;for(;d-1:p.find.matchesSelector(c,a)){f.push(c);break}c=c.parentNode}}return f=f.length>1?p.unique(f):f,this.pushStack(f,"closest",a)},index:function(a){return a?typeof a=="string"?p.inArray(this[0],p(a)):p.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(a,b){var c=typeof a=="string"?p(a,b):p.makeArray(a&&a.nodeType?[a]:a),d=p.merge(this.get(),c);return this.pushStack(bh(c[0])||bh(d[0])?d:p.unique(d))},addBack:function(a){return this.add(a==null?this.prevObject:this.prevObject.filter(a))}}),p.fn.andSelf=p.fn.addBack,p.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return p.dir(a,"parentNode")},parentsUntil:function(a,b,c){return p.dir(a,"parentNode",c)},next:function(a){return bi(a,"nextSibling")},prev:function(a){return bi(a,"previousSibling")},nextAll:function(a){return p.dir(a,"nextSibling")},prevAll:function(a){return p.dir(a,"previousSibling")},nextUntil:function(a,b,c){return p.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return p.dir(a,"previousSibling",c)},siblings:function(a){return p.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return p.sibling(a.firstChild)},contents:function(a){return p.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:p.merge([],a.childNodes)}},function(a,b){p.fn[a]=function(c,d){var e=p.map(this,b,c);return bc.test(a)||(d=c),d&&typeof d=="string"&&(e=p.filter(d,e)),e=this.length>1&&!bg[a]?p.unique(e):e,this.length>1&&bd.test(a)&&(e=e.reverse()),this.pushStack(e,a,k.call(arguments).join(","))}}),p.extend({filter:function(a,b,c){return c&&(a=":not("+a+")"),b.length===1?p.find.matchesSelector(b[0],a)?[b[0]]:[]:p.find.matches(a,b)},dir:function(a,c,d){var e=[],f=a[c];while(f&&f.nodeType!==9&&(d===b||f.nodeType!==1||!p(f).is(d)))f.nodeType===1&&e.push(f),f=f[c];return e},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var bl="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",bm=/ jQuery\d+="(?:null|\d+)"/g,bn=/^\s+/,bo=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bp=/<([\w:]+)/,bq=/]","i"),bv=/^(?:checkbox|radio)$/,bw=/checked\s*(?:[^=]|=\s*.checked.)/i,bx=/\/(java|ecma)script/i,by=/^\s*\s*$/g,bz={option:[1,""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},bA=bk(e),bB=bA.appendChild(e.createElement("div"));bz.optgroup=bz.option,bz.tbody=bz.tfoot=bz.colgroup=bz.caption=bz.thead,bz.th=bz.td,p.support.htmlSerialize||(bz._default=[1,"X
","
"]),p.fn.extend({text:function(a){return p.access(this,function(a){return a===b?p.text(this):this.empty().append((this[0]&&this[0].ownerDocument||e).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(p.isFunction(a))return this.each(function(b){p(this).wrapAll(a.call(this,b))});if(this[0]){var b=p(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return p.isFunction(a)?this.each(function(b){p(this).wrapInner(a.call(this,b))}):this.each(function(){var b=p(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=p.isFunction(a);return this.each(function(c){p(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){p.nodeName(this,"body")||p(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){(this.nodeType===1||this.nodeType===11)&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(a,this.firstChild)})},before:function(){if(!bh(this[0]))return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=p.clean(arguments);return this.pushStack(p.merge(a,this),"before",this.selector)}},after:function(){if(!bh(this[0]))return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=p.clean(arguments);return this.pushStack(p.merge(this,a),"after",this.selector)}},remove:function(a,b){var c,d=0;for(;(c=this[d])!=null;d++)if(!a||p.filter(a,[c]).length)!b&&c.nodeType===1&&(p.cleanData(c.getElementsByTagName("*")),p.cleanData([c])),c.parentNode&&c.parentNode.removeChild(c);return this},empty:function(){var a,b=0;for(;(a=this[b])!=null;b++){a.nodeType===1&&p.cleanData(a.getElementsByTagName("*"));while(a.firstChild)a.removeChild(a.firstChild)}return this},clone:function(a,b){return a=a==null?!1:a,b=b==null?a:b,this.map(function(){return p.clone(this,a,b)})},html:function(a){return p.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(bm,""):b;if(typeof a=="string"&&!bs.test(a)&&(p.support.htmlSerialize||!bu.test(a))&&(p.support.leadingWhitespace||!bn.test(a))&&!bz[(bp.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(bo,"<$1>");try{for(;d1&&typeof j=="string"&&bw.test(j))return this.each(function(){p(this).domManip(a,c,d)});if(p.isFunction(j))return this.each(function(e){var f=p(this);a[0]=j.call(this,e,c?f.html():b),f.domManip(a,c,d)});if(this[0]){e=p.buildFragment(a,this,k),g=e.fragment,f=g.firstChild,g.childNodes.length===1&&(g=f);if(f){c=c&&p.nodeName(f,"tr");for(h=e.cacheable||l-1;i0?this.clone(!0):this).get(),p(g[e])[b](d),f=f.concat(d);return this.pushStack(f,a,g.selector)}}),p.extend({clone:function(a,b,c){var d,e,f,g;p.support.html5Clone||p.isXMLDoc(a)||!bu.test("<"+a.nodeName+">")?g=a.cloneNode(!0):(bB.innerHTML=a.outerHTML,bB.removeChild(g=bB.firstChild));if((!p.support.noCloneEvent||!p.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!p.isXMLDoc(a)){bE(a,g),d=bF(a),e=bF(g);for(f=0;d[f];++f)e[f]&&bE(d[f],e[f])}if(b){bD(a,g);if(c){d=bF(a),e=bF(g);for(f=0;d[f];++f)bD(d[f],e[f])}}return d=e=null,g},clean:function(a,b,c,d){var f,g,h,i,j,k,l,m,n,o,q,r,s=0,t=[];if(!b||typeof b.createDocumentFragment=="undefined")b=e;for(g=b===e&&bA;(h=a[s])!=null;s++){typeof h=="number"&&(h+="");if(!h)continue;if(typeof h=="string")if(!br.test(h))h=b.createTextNode(h);else{g=g||bk(b),l=l||g.appendChild(b.createElement("div")),h=h.replace(bo,"<$1>"),i=(bp.exec(h)||["",""])[1].toLowerCase(),j=bz[i]||bz._default,k=j[0],l.innerHTML=j[1]+h+j[2];while(k--)l=l.lastChild;if(!p.support.tbody){m=bq.test(h),n=i==="table"&&!m?l.firstChild&&l.firstChild.childNodes:j[1]===""&&!m?l.childNodes:[];for(f=n.length-1;f>=0;--f)p.nodeName(n[f],"tbody")&&!n[f].childNodes.length&&n[f].parentNode.removeChild(n[f])}!p.support.leadingWhitespace&&bn.test(h)&&l.insertBefore(b.createTextNode(bn.exec(h)[0]),l.firstChild),h=l.childNodes,l=g.lastChild}h.nodeType?t.push(h):t=p.merge(t,h)}l&&(g.removeChild(l),h=l=g=null);if(!p.support.appendChecked)for(s=0;(h=t[s])!=null;s++)p.nodeName(h,"input")?bG(h):typeof h.getElementsByTagName!="undefined"&&p.grep(h.getElementsByTagName("input"),bG);if(c){q=function(a){if(!a.type||bx.test(a.type))return d?d.push(a.parentNode?a.parentNode.removeChild(a):a):c.appendChild(a)};for(s=0;(h=t[s])!=null;s++)if(!p.nodeName(h,"script")||!q(h))c.appendChild(h),typeof h.getElementsByTagName!="undefined"&&(r=p.grep(p.merge([],h.getElementsByTagName("script")),q),t.splice.apply(t,[s+1,0].concat(r)),s+=r.length)}return t},cleanData:function(a,b){var c,d,e,f,g=0,h=p.expando,i=p.cache,j=p.support.deleteExpando,k=p.event.special;for(;(e=a[g])!=null;g++)if(b||p.acceptData(e)){d=e[h],c=d&&i[d];if(c){if(c.events)for(f in c.events)k[f]?p.event.remove(e,f):p.removeEvent(e,f,c.handle);i[d]&&(delete i[d],j?delete e[h]:e.removeAttribute?e.removeAttribute(h):e[h]=null,p.deletedIds.push(d))}}}}),function(){var a,b;p.uaMatch=function(a){a=a.toLowerCase();var b=/(chrome)[ \/]([\w.]+)/.exec(a)||/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||a.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},a=p.uaMatch(g.userAgent),b={},a.browser&&(b[a.browser]=!0,b.version=a.version),b.webkit&&(b.safari=!0),p.browser=b,p.sub=function(){function a(b,c){return new a.fn.init(b,c)}p.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function c(c,d){return d&&d instanceof p&&!(d instanceof a)&&(d=a(d)),p.fn.init.call(this,c,d,b)},a.fn.init.prototype=a.fn;var b=a(e);return a}}();var bH,bI,bJ,bK=/alpha\([^)]*\)/i,bL=/opacity=([^)]*)/,bM=/^(top|right|bottom|left)$/,bN=/^margin/,bO=new RegExp("^("+q+")(.*)$","i"),bP=new RegExp("^("+q+")(?!px)[a-z%]+$","i"),bQ=new RegExp("^([-+])=("+q+")","i"),bR={},bS={position:"absolute",visibility:"hidden",display:"block"},bT={letterSpacing:0,fontWeight:400,lineHeight:1},bU=["Top","Right","Bottom","Left"],bV=["Webkit","O","Moz","ms"],bW=p.fn.toggle;p.fn.extend({css:function(a,c){return p.access(this,function(a,c,d){return d!==b?p.style(a,c,d):p.css(a,c)},a,c,arguments.length>1)},show:function(){return bZ(this,!0)},hide:function(){return bZ(this)},toggle:function(a,b){var c=typeof a=="boolean";return p.isFunction(a)&&p.isFunction(b)?bW.apply(this,arguments):this.each(function(){(c?a:bY(this))?p(this).show():p(this).hide()})}}),p.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bH(a,"opacity");return c===""?"1":c}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":p.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!a||a.nodeType===3||a.nodeType===8||!a.style)return;var f,g,h,i=p.camelCase(c),j=a.style;c=p.cssProps[i]||(p.cssProps[i]=bX(j,i)),h=p.cssHooks[c]||p.cssHooks[i];if(d===b)return h&&"get"in h&&(f=h.get(a,!1,e))!==b?f:j[c];g=typeof d,g==="string"&&(f=bQ.exec(d))&&(d=(f[1]+1)*f[2]+parseFloat(p.css(a,c)),g="number");if(d==null||g==="number"&&isNaN(d))return;g==="number"&&!p.cssNumber[i]&&(d+="px");if(!h||!("set"in h)||(d=h.set(a,d,e))!==b)try{j[c]=d}catch(k){}},css:function(a,c,d,e){var f,g,h,i=p.camelCase(c);return c=p.cssProps[i]||(p.cssProps[i]=bX(a.style,i)),h=p.cssHooks[c]||p.cssHooks[i],h&&"get"in h&&(f=h.get(a,!0,e)),f===b&&(f=bH(a,c)),f==="normal"&&c in bT&&(f=bT[c]),d||e!==b?(g=parseFloat(f),d||p.isNumeric(g)?g||0:f):f},swap:function(a,b,c){var d,e,f={};for(e in b)f[e]=a.style[e],a.style[e]=b[e];d=c.call(a);for(e in b)a.style[e]=f[e];return d}}),a.getComputedStyle?bH=function(a,b){var c,d,e,f,g=getComputedStyle(a,null),h=a.style;return g&&(c=g[b],c===""&&!p.contains(a.ownerDocument.documentElement,a)&&(c=p.style(a,b)),bP.test(c)&&bN.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=c,c=g.width,h.width=d,h.minWidth=e,h.maxWidth=f)),c}:e.documentElement.currentStyle&&(bH=function(a,b){var c,d,e=a.currentStyle&&a.currentStyle[b],f=a.style;return e==null&&f&&f[b]&&(e=f[b]),bP.test(e)&&!bM.test(b)&&(c=f.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":e,e=f.pixelLeft+"px",f.left=c,d&&(a.runtimeStyle.left=d)),e===""?"auto":e}),p.each(["height","width"],function(a,b){p.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth!==0||bH(a,"display")!=="none"?ca(a,b,d):p.swap(a,bS,function(){return ca(a,b,d)})},set:function(a,c,d){return b$(a,c,d?b_(a,b,d,p.support.boxSizing&&p.css(a,"boxSizing")==="border-box"):0)}}}),p.support.opacity||(p.cssHooks.opacity={get:function(a,b){return bL.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=p.isNumeric(b)?"alpha(opacity="+b*100+")":"",f=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&p.trim(f.replace(bK,""))===""&&c.removeAttribute){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bK.test(f)?f.replace(bK,e):f+" "+e}}),p(function(){p.support.reliableMarginRight||(p.cssHooks.marginRight={get:function(a,b){return p.swap(a,{display:"inline-block"},function(){if(b)return bH(a,"marginRight")})}}),!p.support.pixelPosition&&p.fn.position&&p.each(["top","left"],function(a,b){p.cssHooks[b]={get:function(a,c){if(c){var d=bH(a,b);return bP.test(d)?p(a).position()[b]+"px":d}}}})}),p.expr&&p.expr.filters&&(p.expr.filters.hidden=function(a){return a.offsetWidth===0&&a.offsetHeight===0||!p.support.reliableHiddenOffsets&&(a.style&&a.style.display||bH(a,"display"))==="none"},p.expr.filters.visible=function(a){return!p.expr.filters.hidden(a)}),p.each({margin:"",padding:"",border:"Width"},function(a,b){p.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bU[d]+b]=e[d]||e[d-2]||e[0];return f}},bN.test(a)||(p.cssHooks[a+b].set=b$)});var cc=/%20/g,cd=/\[\]$/,ce=/\r?\n/g,cf=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,cg=/^(?:select|textarea)/i;p.fn.extend({serialize:function(){return p.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?p.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||cg.test(this.nodeName)||cf.test(this.type))}).map(function(a,b){var c=p(this).val();return c==null?null:p.isArray(c)?p.map(c,function(a,c){return{name:b.name,value:a.replace(ce,"\r\n")}}):{name:b.name,value:c.replace(ce,"\r\n")}}).get()}}),p.param=function(a,c){var d,e=[],f=function(a,b){b=p.isFunction(b)?b():b==null?"":b,e[e.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=p.ajaxSettings&&p.ajaxSettings.traditional);if(p.isArray(a)||a.jquery&&!p.isPlainObject(a))p.each(a,function(){f(this.name,this.value)});else for(d in a)ch(d,a[d],c,f);return e.join("&").replace(cc,"+")};var ci,cj,ck=/#.*$/,cl=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,cm=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,cn=/^(?:GET|HEAD)$/,co=/^\/\//,cp=/\?/,cq=/)<[^<]*)*<\/script>/gi,cr=/([?&])_=[^&]*/,cs=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,ct=p.fn.load,cu={},cv={},cw=["*/"]+["*"];try{ci=f.href}catch(cx){ci=e.createElement("a"),ci.href="",ci=ci.href}cj=cs.exec(ci.toLowerCase())||[],p.fn.load=function(a,c,d){if(typeof a!="string"&&ct)return ct.apply(this,arguments);if(!this.length)return this;var e,f,g,h=this,i=a.indexOf(" ");return i>=0&&(e=a.slice(i,a.length),a=a.slice(0,i)),p.isFunction(c)?(d=c,c=b):typeof c=="object"&&(f="POST"),p.ajax({url:a,type:f,dataType:"html",data:c,complete:function(a,b){d&&h.each(d,g||[a.responseText,b,a])}}).done(function(a){g=arguments,h.html(e?p("
").append(a.replace(cq,"")).find(e):a)}),this},p.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){p.fn[b]=function(a){return this.on(b,a)}}),p.each(["get","post"],function(a,c){p[c]=function(a,d,e,f){return p.isFunction(d)&&(f=f||e,e=d,d=b),p.ajax({type:c,url:a,data:d,success:e,dataType:f})}}),p.extend({getScript:function(a,c){return p.get(a,b,c,"script")},getJSON:function(a,b,c){return p.get(a,b,c,"json")},ajaxSetup:function(a,b){return b?cA(a,p.ajaxSettings):(b=a,a=p.ajaxSettings),cA(a,b),a},ajaxSettings:{url:ci,isLocal:cm.test(cj[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":cw},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":p.parseJSON,"text xml":p.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:cy(cu),ajaxTransport:cy(cv),ajax:function(a,c){function y(a,c,f,i){var k,s,t,u,w,y=c;if(v===2)return;v=2,h&&clearTimeout(h),g=b,e=i||"",x.readyState=a>0?4:0,f&&(u=cB(l,x,f));if(a>=200&&a<300||a===304)l.ifModified&&(w=x.getResponseHeader("Last-Modified"),w&&(p.lastModified[d]=w),w=x.getResponseHeader("Etag"),w&&(p.etag[d]=w)),a===304?(y="notmodified",k=!0):(k=cC(l,u),y=k.state,s=k.data,t=k.error,k=!t);else{t=y;if(!y||a)y="error",a<0&&(a=0)}x.status=a,x.statusText=""+(c||y),k?o.resolveWith(m,[s,y,x]):o.rejectWith(m,[x,y,t]),x.statusCode(r),r=b,j&&n.trigger("ajax"+(k?"Success":"Error"),[x,l,k?s:t]),q.fireWith(m,[x,y]),j&&(n.trigger("ajaxComplete",[x,l]),--p.active||p.event.trigger("ajaxStop"))}typeof a=="object"&&(c=a,a=b),c=c||{};var d,e,f,g,h,i,j,k,l=p.ajaxSetup({},c),m=l.context||l,n=m!==l&&(m.nodeType||m instanceof p)?p(m):p.event,o=p.Deferred(),q=p.Callbacks("once memory"),r=l.statusCode||{},t={},u={},v=0,w="canceled",x={readyState:0,setRequestHeader:function(a,b){if(!v){var c=a.toLowerCase();a=u[c]=u[c]||a,t[a]=b}return this},getAllResponseHeaders:function(){return v===2?e:null},getResponseHeader:function(a){var c;if(v===2){if(!f){f={};while(c=cl.exec(e))f[c[1].toLowerCase()]=c[2]}c=f[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){return v||(l.mimeType=a),this},abort:function(a){return a=a||w,g&&g.abort(a),y(0,a),this}};o.promise(x),x.success=x.done,x.error=x.fail,x.complete=q.add,x.statusCode=function(a){if(a){var b;if(v<2)for(b in a)r[b]=[r[b],a[b]];else b=a[x.status],x.always(b)}return this},l.url=((a||l.url)+"").replace(ck,"").replace(co,cj[1]+"//"),l.dataTypes=p.trim(l.dataType||"*").toLowerCase().split(s),l.crossDomain==null&&(i=cs.exec(l.url.toLowerCase()),l.crossDomain=!(!i||i[1]==cj[1]&&i[2]==cj[2]&&(i[3]||(i[1]==="http:"?80:443))==(cj[3]||(cj[1]==="http:"?80:443)))),l.data&&l.processData&&typeof l.data!="string"&&(l.data=p.param(l.data,l.traditional)),cz(cu,l,c,x);if(v===2)return x;j=l.global,l.type=l.type.toUpperCase(),l.hasContent=!cn.test(l.type),j&&p.active++===0&&p.event.trigger("ajaxStart");if(!l.hasContent){l.data&&(l.url+=(cp.test(l.url)?"&":"?")+l.data,delete l.data),d=l.url;if(l.cache===!1){var z=p.now(),A=l.url.replace(cr,"$1_="+z);l.url=A+(A===l.url?(cp.test(l.url)?"&":"?")+"_="+z:"")}}(l.data&&l.hasContent&&l.contentType!==!1||c.contentType)&&x.setRequestHeader("Content-Type",l.contentType),l.ifModified&&(d=d||l.url,p.lastModified[d]&&x.setRequestHeader("If-Modified-Since",p.lastModified[d]),p.etag[d]&&x.setRequestHeader("If-None-Match",p.etag[d])),x.setRequestHeader("Accept",l.dataTypes[0]&&l.accepts[l.dataTypes[0]]?l.accepts[l.dataTypes[0]]+(l.dataTypes[0]!=="*"?", "+cw+"; q=0.01":""):l.accepts["*"]);for(k in l.headers)x.setRequestHeader(k,l.headers[k]);if(!l.beforeSend||l.beforeSend.call(m,x,l)!==!1&&v!==2){w="abort";for(k in{success:1,error:1,complete:1})x[k](l[k]);g=cz(cv,l,c,x);if(!g)y(-1,"No Transport");else{x.readyState=1,j&&n.trigger("ajaxSend",[x,l]),l.async&&l.timeout>0&&(h=setTimeout(function(){x.abort("timeout")},l.timeout));try{v=1,g.send(t,y)}catch(B){if(v<2)y(-1,B);else throw B}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var cD=[],cE=/\?/,cF=/(=)\?(?=&|$)|\?\?/,cG=p.now();p.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=cD.pop()||p.expando+"_"+cG++;return this[a]=!0,a}}),p.ajaxPrefilter("json jsonp",function(c,d,e){var f,g,h,i=c.data,j=c.url,k=c.jsonp!==!1,l=k&&cF.test(j),m=k&&!l&&typeof i=="string"&&!(c.contentType||"").indexOf("application/x-www-form-urlencoded")&&cF.test(i);if(c.dataTypes[0]==="jsonp"||l||m)return f=c.jsonpCallback=p.isFunction(c.jsonpCallback)?c.jsonpCallback():c.jsonpCallback,g=a[f],l?c.url=j.replace(cF,"$1"+f):m?c.data=i.replace(cF,"$1"+f):k&&(c.url+=(cE.test(j)?"&":"?")+c.jsonp+"="+f),c.converters["script json"]=function(){return h||p.error(f+" was not called"),h[0]},c.dataTypes[0]="json",a[f]=function(){h=arguments},e.always(function(){a[f]=g,c[f]&&(c.jsonpCallback=d.jsonpCallback,cD.push(f)),h&&p.isFunction(g)&&g(h[0]),h=g=b}),"script"}),p.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){return p.globalEval(a),a}}}),p.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),p.ajaxTransport("script",function(a){if(a.crossDomain){var c,d=e.head||e.getElementsByTagName("head")[0]||e.documentElement;return{send:function(f,g){c=e.createElement("script"),c.async="async",a.scriptCharset&&(c.charset=a.scriptCharset),c.src=a.url,c.onload=c.onreadystatechange=function(a,e){if(e||!c.readyState||/loaded|complete/.test(c.readyState))c.onload=c.onreadystatechange=null,d&&c.parentNode&&d.removeChild(c),c=b,e||g(200,"success")},d.insertBefore(c,d.firstChild)},abort:function(){c&&c.onload(0,1)}}}});var cH,cI=a.ActiveXObject?function(){for(var a in cH)cH[a](0,1)}:!1,cJ=0;p.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&cK()||cL()}:cK,function(a){p.extend(p.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(p.ajaxSettings.xhr()),p.support.ajax&&p.ajaxTransport(function(c){if(!c.crossDomain||p.support.cors){var d;return{send:function(e,f){var g,h,i=c.xhr();c.username?i.open(c.type,c.url,c.async,c.username,c.password):i.open(c.type,c.url,c.async);if(c.xhrFields)for(h in c.xhrFields)i[h]=c.xhrFields[h];c.mimeType&&i.overrideMimeType&&i.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(h in e)i.setRequestHeader(h,e[h])}catch(j){}i.send(c.hasContent&&c.data||null),d=function(a,e){var h,j,k,l,m;try{if(d&&(e||i.readyState===4)){d=b,g&&(i.onreadystatechange=p.noop,cI&&delete cH[g]);if(e)i.readyState!==4&&i.abort();else{h=i.status,k=i.getAllResponseHeaders(),l={},m=i.responseXML,m&&m.documentElement&&(l.xml=m);try{l.text=i.responseText}catch(a){}try{j=i.statusText}catch(n){j=""}!h&&c.isLocal&&!c.crossDomain?h=l.text?200:404:h===1223&&(h=204)}}}catch(o){e||f(-1,o)}l&&f(h,j,l,k)},c.async?i.readyState===4?setTimeout(d,0):(g=++cJ,cI&&(cH||(cH={},p(a).unload(cI)),cH[g]=d),i.onreadystatechange=d):d()},abort:function(){d&&d(0,1)}}}});var cM,cN,cO=/^(?:toggle|show|hide)$/,cP=new RegExp("^(?:([-+])=|)("+q+")([a-z%]*)$","i"),cQ=/queueHooks$/,cR=[cX],cS={"*":[function(a,b){var c,d,e,f=this.createTween(a,b),g=cP.exec(b),h=f.cur(),i=+h||0,j=1;if(g){c=+g[2],d=g[3]||(p.cssNumber[a]?"":"px");if(d!=="px"&&i){i=p.css(f.elem,a,!0)||c||1;do e=j=j||".5",i=i/j,p.style(f.elem,a,i+d),j=f.cur()/h;while(j!==1&&j!==e)}f.unit=d,f.start=i,f.end=g[1]?i+(g[1]+1)*c:c}return f}]};p.Animation=p.extend(cV,{tweener:function(a,b){p.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");var c,d=0,e=a.length;for(;d-1,j={},k={},l,m;i?(k=e.position(),l=k.top,m=k.left):(l=parseFloat(g)||0,m=parseFloat(h)||0),p.isFunction(b)&&(b=b.call(a,c,f)),b.top!=null&&(j.top=b.top-f.top+l),b.left!=null&&(j.left=b.left-f.left+m),"using"in b?b.using.call(a,j):e.css(j)}},p.fn.extend({position:function(){if(!this[0])return;var a=this[0],b=this.offsetParent(),c=this.offset(),d=c$.test(b[0].nodeName)?{top:0,left:0}:b.offset();return c.top-=parseFloat(p.css(a,"marginTop"))||0,c.left-=parseFloat(p.css(a,"marginLeft"))||0,d.top+=parseFloat(p.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(p.css(b[0],"borderLeftWidth"))||0,{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||e.body;while(a&&!c$.test(a.nodeName)&&p.css(a,"position")==="static")a=a.offsetParent;return a||e.body})}}),p.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);p.fn[a]=function(e){return p.access(this,function(a,e,f){var g=c_(a);if(f===b)return g?c in g?g[c]:g.document.documentElement[e]:a[e];g?g.scrollTo(d?p(g).scrollLeft():f,d?f:p(g).scrollTop()):a[e]=f},a,e,arguments.length,null)}}),p.each({Height:"height",Width:"width"},function(a,c){p.each({padding:"inner"+a,content:c,"":"outer"+a},function(d,e){p.fn[e]=function(e,f){var g=arguments.length&&(d||typeof e!="boolean"),h=d||(e===!0||f===!0?"margin":"border");return p.access(this,function(c,d,e){var f;return p.isWindow(c)?c.document.documentElement["client"+a]:c.nodeType===9?(f=c.documentElement,Math.max(c.body["scroll"+a],f["scroll"+a],c.body["offset"+a],f["offset"+a],f["client"+a])):e===b?p.css(c,d,e,h):p.style(c,d,e,h)},c,g?e:b,g)}})}),a.jQuery=a.$=p,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return p})})(window); \ No newline at end of file diff --git a/lib/raphael-min.js b/lib/raphael-min.js deleted file mode 100644 index d30dbad8..00000000 --- a/lib/raphael-min.js +++ /dev/null @@ -1,10 +0,0 @@ -// ┌────────────────────────────────────────────────────────────────────┐ \\ -// │ Raphaël 2.1.0 - JavaScript Vector Library │ \\ -// ├────────────────────────────────────────────────────────────────────┤ \\ -// │ Copyright © 2008-2012 Dmitry Baranovskiy (http://raphaeljs.com) │ \\ -// │ Copyright © 2008-2012 Sencha Labs (http://sencha.com) │ \\ -// ├────────────────────────────────────────────────────────────────────┤ \\ -// │ Licensed under the MIT (http://raphaeljs.com/license.html) license.│ \\ -// └────────────────────────────────────────────────────────────────────┘ \\ - -(function(a){var b="0.3.4",c="hasOwnProperty",d=/[\.\/]/,e="*",f=function(){},g=function(a,b){return a-b},h,i,j={n:{}},k=function(a,b){var c=j,d=i,e=Array.prototype.slice.call(arguments,2),f=k.listeners(a),l=0,m=!1,n,o=[],p={},q=[],r=h,s=[];h=a,i=0;for(var t=0,u=f.length;tf*b.top){e=b.percents[y],p=b.percents[y-1]||0,t=t/b.top*(e-p),o=b.percents[y+1],j=b.anim[e];break}f&&d.attr(b.anim[b.percents[y]])}if(!!j){if(!k){for(var A in j)if(j[g](A))if(U[g](A)||d.paper.customAttributes[g](A)){u[A]=d.attr(A),u[A]==null&&(u[A]=T[A]),v[A]=j[A];switch(U[A]){case C:w[A]=(v[A]-u[A])/t;break;case"colour":u[A]=a.getRGB(u[A]);var B=a.getRGB(v[A]);w[A]={r:(B.r-u[A].r)/t,g:(B.g-u[A].g)/t,b:(B.b-u[A].b)/t};break;case"path":var D=bR(u[A],v[A]),E=D[1];u[A]=D[0],w[A]=[];for(y=0,z=u[A].length;yd)return d;while(cf?c=e:d=e,e=(d-c)/2+c}return e}function n(a,b){var c=o(a,b);return((l*c+k)*c+j)*c}function m(a){return((i*a+h)*a+g)*a}var g=3*b,h=3*(d-b)-g,i=1-g-h,j=3*c,k=3*(e-c)-j,l=1-j-k;return n(a,1/(200*f))}function cq(){return this.x+q+this.y+q+this.width+" × "+this.height}function cp(){return this.x+q+this.y}function cb(a,b,c,d,e,f){a!=null?(this.a=+a,this.b=+b,this.c=+c,this.d=+d,this.e=+e,this.f=+f):(this.a=1,this.b=0,this.c=0,this.d=1,this.e=0,this.f=0)}function bH(b,c,d){b=a._path2curve(b),c=a._path2curve(c);var e,f,g,h,i,j,k,l,m,n,o=d?0:[];for(var p=0,q=b.length;p=0&&y<=1&&A>=0&&A<=1&&(d?n++:n.push({x:x.x,y:x.y,t1:y,t2:A}))}}return n}function bF(a,b){return bG(a,b,1)}function bE(a,b){return bG(a,b)}function bD(a,b,c,d,e,f,g,h){if(!(x(a,c)x(e,g)||x(b,d)x(f,h))){var i=(a*d-b*c)*(e-g)-(a-c)*(e*h-f*g),j=(a*d-b*c)*(f-h)-(b-d)*(e*h-f*g),k=(a-c)*(f-h)-(b-d)*(e-g);if(!k)return;var l=i/k,m=j/k,n=+l.toFixed(2),o=+m.toFixed(2);if(n<+y(a,c).toFixed(2)||n>+x(a,c).toFixed(2)||n<+y(e,g).toFixed(2)||n>+x(e,g).toFixed(2)||o<+y(b,d).toFixed(2)||o>+x(b,d).toFixed(2)||o<+y(f,h).toFixed(2)||o>+x(f,h).toFixed(2))return;return{x:l,y:m}}}function bC(a,b,c,d,e,f,g,h,i){if(!(i<0||bB(a,b,c,d,e,f,g,h)n)k/=2,l+=(m1?1:i<0?0:i;var j=i/2,k=12,l=[-0.1252,.1252,-0.3678,.3678,-0.5873,.5873,-0.7699,.7699,-0.9041,.9041,-0.9816,.9816],m=[.2491,.2491,.2335,.2335,.2032,.2032,.1601,.1601,.1069,.1069,.0472,.0472],n=0;for(var o=0;od;d+=2){var f=[{x:+a[d-2],y:+a[d-1]},{x:+a[d],y:+a[d+1]},{x:+a[d+2],y:+a[d+3]},{x:+a[d+4],y:+a[d+5]}];b?d?e-4==d?f[3]={x:+a[0],y:+a[1]}:e-2==d&&(f[2]={x:+a[0],y:+a[1]},f[3]={x:+a[2],y:+a[3]}):f[0]={x:+a[e-2],y:+a[e-1]}:e-4==d?f[3]=f[2]:d||(f[0]={x:+a[d],y:+a[d+1]}),c.push(["C",(-f[0].x+6*f[1].x+f[2].x)/6,(-f[0].y+6*f[1].y+f[2].y)/6,(f[1].x+6*f[2].x-f[3].x)/6,(f[1].y+6*f[2].y-f[3].y)/6,f[2].x,f[2].y])}return c}function bx(){return this.hex}function bv(a,b,c){function d(){var e=Array.prototype.slice.call(arguments,0),f=e.join("␀"),h=d.cache=d.cache||{},i=d.count=d.count||[];if(h[g](f)){bu(i,f);return c?c(h[f]):h[f]}i.length>=1e3&&delete h[i.shift()],i.push(f),h[f]=a[m](b,e);return c?c(h[f]):h[f]}return d}function bu(a,b){for(var c=0,d=a.length;c',bl=bk.firstChild,bl.style.behavior="url(#default#VML)";if(!bl||typeof bl.adj!="object")return a.type=p;bk=null}a.svg=!(a.vml=a.type=="VML"),a._Paper=j,a.fn=k=j.prototype=a.prototype,a._id=0,a._oid=0,a.is=function(a,b){b=v.call(b);if(b=="finite")return!M[g](+a);if(b=="array")return a instanceof Array;return b=="null"&&a===null||b==typeof a&&a!==null||b=="object"&&a===Object(a)||b=="array"&&Array.isArray&&Array.isArray(a)||H.call(a).slice(8,-1).toLowerCase()==b},a.angle=function(b,c,d,e,f,g){if(f==null){var h=b-d,i=c-e;if(!h&&!i)return 0;return(180+w.atan2(-i,-h)*180/B+360)%360}return a.angle(b,c,f,g)-a.angle(d,e,f,g)},a.rad=function(a){return a%360*B/180},a.deg=function(a){return a*180/B%360},a.snapTo=function(b,c,d){d=a.is(d,"finite")?d:10;if(a.is(b,E)){var e=b.length;while(e--)if(z(b[e]-c)<=d)return b[e]}else{b=+b;var f=c%b;if(fb-d)return c-f+b}return c};var bn=a.createUUID=function(a,b){return function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(a,b).toUpperCase()}}(/[xy]/g,function(a){var b=w.random()*16|0,c=a=="x"?b:b&3|8;return c.toString(16)});a.setWindow=function(b){eve("raphael.setWindow",a,h.win,b),h.win=b,h.doc=h.win.document,a._engine.initWin&&a._engine.initWin(h.win)};var bo=function(b){if(a.vml){var c=/^\s+|\s+$/g,d;try{var e=new ActiveXObject("htmlfile");e.write(""),e.close(),d=e.body}catch(f){d=createPopup().document.body}var g=d.createTextRange();bo=bv(function(a){try{d.style.color=r(a).replace(c,p);var b=g.queryCommandValue("ForeColor");b=(b&255)<<16|b&65280|(b&16711680)>>>16;return"#"+("000000"+b.toString(16)).slice(-6)}catch(e){return"none"}})}else{var i=h.doc.createElement("i");i.title="Raphaël Colour Picker",i.style.display="none",h.doc.body.appendChild(i),bo=bv(function(a){i.style.color=a;return h.doc.defaultView.getComputedStyle(i,p).getPropertyValue("color")})}return bo(b)},bp=function(){return"hsb("+[this.h,this.s,this.b]+")"},bq=function(){return"hsl("+[this.h,this.s,this.l]+")"},br=function(){return this.hex},bs=function(b,c,d){c==null&&a.is(b,"object")&&"r"in b&&"g"in b&&"b"in b&&(d=b.b,c=b.g,b=b.r);if(c==null&&a.is(b,D)){var e=a.getRGB(b);b=e.r,c=e.g,d=e.b}if(b>1||c>1||d>1)b/=255,c/=255,d/=255;return[b,c,d]},bt=function(b,c,d,e){b*=255,c*=255,d*=255;var f={r:b,g:c,b:d,hex:a.rgb(b,c,d),toString:br};a.is(e,"finite")&&(f.opacity=e);return f};a.color=function(b){var c;a.is(b,"object")&&"h"in b&&"s"in b&&"b"in b?(c=a.hsb2rgb(b),b.r=c.r,b.g=c.g,b.b=c.b,b.hex=c.hex):a.is(b,"object")&&"h"in b&&"s"in b&&"l"in b?(c=a.hsl2rgb(b),b.r=c.r,b.g=c.g,b.b=c.b,b.hex=c.hex):(a.is(b,"string")&&(b=a.getRGB(b)),a.is(b,"object")&&"r"in b&&"g"in b&&"b"in b?(c=a.rgb2hsl(b),b.h=c.h,b.s=c.s,b.l=c.l,c=a.rgb2hsb(b),b.v=c.b):(b={hex:"none"},b.r=b.g=b.b=b.h=b.s=b.v=b.l=-1)),b.toString=br;return b},a.hsb2rgb=function(a,b,c,d){this.is(a,"object")&&"h"in a&&"s"in a&&"b"in a&&(c=a.b,b=a.s,a=a.h,d=a.o),a*=360;var e,f,g,h,i;a=a%360/60,i=c*b,h=i*(1-z(a%2-1)),e=f=g=c-i,a=~~a,e+=[i,h,0,0,h,i][a],f+=[h,i,i,h,0,0][a],g+=[0,0,h,i,i,h][a];return bt(e,f,g,d)},a.hsl2rgb=function(a,b,c,d){this.is(a,"object")&&"h"in a&&"s"in a&&"l"in a&&(c=a.l,b=a.s,a=a.h);if(a>1||b>1||c>1)a/=360,b/=100,c/=100;a*=360;var e,f,g,h,i;a=a%360/60,i=2*b*(c<.5?c:1-c),h=i*(1-z(a%2-1)),e=f=g=c-i/2,a=~~a,e+=[i,h,0,0,h,i][a],f+=[h,i,i,h,0,0][a],g+=[0,0,h,i,i,h][a];return bt(e,f,g,d)},a.rgb2hsb=function(a,b,c){c=bs(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g;f=x(a,b,c),g=f-y(a,b,c),d=g==0?null:f==a?(b-c)/g:f==b?(c-a)/g+2:(a-b)/g+4,d=(d+360)%6*60/360,e=g==0?0:g/f;return{h:d,s:e,b:f,toString:bp}},a.rgb2hsl=function(a,b,c){c=bs(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g,h,i;g=x(a,b,c),h=y(a,b,c),i=g-h,d=i==0?null:g==a?(b-c)/i:g==b?(c-a)/i+2:(a-b)/i+4,d=(d+360)%6*60/360,f=(g+h)/2,e=i==0?0:f<.5?i/(2*f):i/(2-2*f);return{h:d,s:e,l:f,toString:bq}},a._path2string=function(){return this.join(",").replace(Y,"$1")};var bw=a._preload=function(a,b){var c=h.doc.createElement("img");c.style.cssText="position:absolute;left:-9999em;top:-9999em",c.onload=function(){b.call(this),this.onload=null,h.doc.body.removeChild(this)},c.onerror=function(){h.doc.body.removeChild(this)},h.doc.body.appendChild(c),c.src=a};a.getRGB=bv(function(b){if(!b||!!((b=r(b)).indexOf("-")+1))return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:bx};if(b=="none")return{r:-1,g:-1,b:-1,hex:"none",toString:bx};!X[g](b.toLowerCase().substring(0,2))&&b.charAt()!="#"&&(b=bo(b));var c,d,e,f,h,i,j,k=b.match(L);if(k){k[2]&&(f=R(k[2].substring(5),16),e=R(k[2].substring(3,5),16),d=R(k[2].substring(1,3),16)),k[3]&&(f=R((i=k[3].charAt(3))+i,16),e=R((i=k[3].charAt(2))+i,16),d=R((i=k[3].charAt(1))+i,16)),k[4]&&(j=k[4][s](W),d=Q(j[0]),j[0].slice(-1)=="%"&&(d*=2.55),e=Q(j[1]),j[1].slice(-1)=="%"&&(e*=2.55),f=Q(j[2]),j[2].slice(-1)=="%"&&(f*=2.55),k[1].toLowerCase().slice(0,4)=="rgba"&&(h=Q(j[3])),j[3]&&j[3].slice(-1)=="%"&&(h/=100));if(k[5]){j=k[5][s](W),d=Q(j[0]),j[0].slice(-1)=="%"&&(d*=2.55),e=Q(j[1]),j[1].slice(-1)=="%"&&(e*=2.55),f=Q(j[2]),j[2].slice(-1)=="%"&&(f*=2.55),(j[0].slice(-3)=="deg"||j[0].slice(-1)=="°")&&(d/=360),k[1].toLowerCase().slice(0,4)=="hsba"&&(h=Q(j[3])),j[3]&&j[3].slice(-1)=="%"&&(h/=100);return a.hsb2rgb(d,e,f,h)}if(k[6]){j=k[6][s](W),d=Q(j[0]),j[0].slice(-1)=="%"&&(d*=2.55),e=Q(j[1]),j[1].slice(-1)=="%"&&(e*=2.55),f=Q(j[2]),j[2].slice(-1)=="%"&&(f*=2.55),(j[0].slice(-3)=="deg"||j[0].slice(-1)=="°")&&(d/=360),k[1].toLowerCase().slice(0,4)=="hsla"&&(h=Q(j[3])),j[3]&&j[3].slice(-1)=="%"&&(h/=100);return a.hsl2rgb(d,e,f,h)}k={r:d,g:e,b:f,toString:bx},k.hex="#"+(16777216|f|e<<8|d<<16).toString(16).slice(1),a.is(h,"finite")&&(k.opacity=h);return k}return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:bx}},a),a.hsb=bv(function(b,c,d){return a.hsb2rgb(b,c,d).hex}),a.hsl=bv(function(b,c,d){return a.hsl2rgb(b,c,d).hex}),a.rgb=bv(function(a,b,c){return"#"+(16777216|c|b<<8|a<<16).toString(16).slice(1)}),a.getColor=function(a){var b=this.getColor.start=this.getColor.start||{h:0,s:1,b:a||.75},c=this.hsb2rgb(b.h,b.s,b.b);b.h+=.075,b.h>1&&(b.h=0,b.s-=.2,b.s<=0&&(this.getColor.start={h:0,s:1,b:b.b}));return c.hex},a.getColor.reset=function(){delete this.start},a.parsePathString=function(b){if(!b)return null;var c=bz(b);if(c.arr)return bJ(c.arr);var d={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0},e=[];a.is(b,E)&&a.is(b[0],E)&&(e=bJ(b)),e.length||r(b).replace(Z,function(a,b,c){var f=[],g=b.toLowerCase();c.replace(_,function(a,b){b&&f.push(+b)}),g=="m"&&f.length>2&&(e.push([b][n](f.splice(0,2))),g="l",b=b=="m"?"l":"L");if(g=="r")e.push([b][n](f));else while(f.length>=d[g]){e.push([b][n](f.splice(0,d[g])));if(!d[g])break}}),e.toString=a._path2string,c.arr=bJ(e);return e},a.parseTransformString=bv(function(b){if(!b)return null;var c={r:3,s:4,t:2,m:6},d=[];a.is(b,E)&&a.is(b[0],E)&&(d=bJ(b)),d.length||r(b).replace($,function(a,b,c){var e=[],f=v.call(b);c.replace(_,function(a,b){b&&e.push(+b)}),d.push([b][n](e))}),d.toString=a._path2string;return d});var bz=function(a){var b=bz.ps=bz.ps||{};b[a]?b[a].sleep=100:b[a]={sleep:100},setTimeout(function(){for(var c in b)b[g](c)&&c!=a&&(b[c].sleep--,!b[c].sleep&&delete b[c])});return b[a]};a.findDotsAtSegment=function(a,b,c,d,e,f,g,h,i){var j=1-i,k=A(j,3),l=A(j,2),m=i*i,n=m*i,o=k*a+l*3*i*c+j*3*i*i*e+n*g,p=k*b+l*3*i*d+j*3*i*i*f+n*h,q=a+2*i*(c-a)+m*(e-2*c+a),r=b+2*i*(d-b)+m*(f-2*d+b),s=c+2*i*(e-c)+m*(g-2*e+c),t=d+2*i*(f-d)+m*(h-2*f+d),u=j*a+i*c,v=j*b+i*d,x=j*e+i*g,y=j*f+i*h,z=90-w.atan2(q-s,r-t)*180/B;(q>s||r=a.x&&b<=a.x2&&c>=a.y&&c<=a.y2},a.isBBoxIntersect=function(b,c){var d=a.isPointInsideBBox;return d(c,b.x,b.y)||d(c,b.x2,b.y)||d(c,b.x,b.y2)||d(c,b.x2,b.y2)||d(b,c.x,c.y)||d(b,c.x2,c.y)||d(b,c.x,c.y2)||d(b,c.x2,c.y2)||(b.xc.x||c.xb.x)&&(b.yc.y||c.yb.y)},a.pathIntersection=function(a,b){return bH(a,b)},a.pathIntersectionNumber=function(a,b){return bH(a,b,1)},a.isPointInsidePath=function(b,c,d){var e=a.pathBBox(b);return a.isPointInsideBBox(e,c,d)&&bH(b,[["M",c,d],["H",e.x2+10]],1)%2==1},a._removedFactory=function(a){return function(){eve("raphael.log",null,"Raphaël: you are calling to method “"+a+"” of removed object",a)}};var bI=a.pathBBox=function(a){var b=bz(a);if(b.bbox)return b.bbox;if(!a)return{x:0,y:0,width:0,height:0,x2:0,y2:0};a=bR(a);var c=0,d=0,e=[],f=[],g;for(var h=0,i=a.length;h1&&(v=w.sqrt(v),c=v*c,d=v*d);var x=c*c,y=d*d,A=(f==g?-1:1)*w.sqrt(z((x*y-x*u*u-y*t*t)/(x*u*u+y*t*t))),C=A*c*u/d+(a+h)/2,D=A*-d*t/c+(b+i)/2,E=w.asin(((b-D)/d).toFixed(9)),F=w.asin(((i-D)/d).toFixed(9));E=aF&&(E=E-B*2),!g&&F>E&&(F=F-B*2)}else E=j[0],F=j[1],C=j[2],D=j[3];var G=F-E;if(z(G)>k){var H=F,I=h,J=i;F=E+k*(g&&F>E?1:-1),h=C+c*w.cos(F),i=D+d*w.sin(F),m=bO(h,i,c,d,e,0,g,I,J,[F,H,C,D])}G=F-E;var K=w.cos(E),L=w.sin(E),M=w.cos(F),N=w.sin(F),O=w.tan(G/4),P=4/3*c*O,Q=4/3*d*O,R=[a,b],S=[a+P*L,b-Q*K],T=[h+P*N,i-Q*M],U=[h,i];S[0]=2*R[0]-S[0],S[1]=2*R[1]-S[1];if(j)return[S,T,U][n](m);m=[S,T,U][n](m).join()[s](",");var V=[];for(var W=0,X=m.length;W"1e12"&&(l=.5),z(n)>"1e12"&&(n=.5),l>0&&l<1&&(q=bP(a,b,c,d,e,f,g,h,l),p.push(q.x),o.push(q.y)),n>0&&n<1&&(q=bP(a,b,c,d,e,f,g,h,n),p.push(q.x),o.push(q.y)),i=f-2*d+b-(h-2*f+d),j=2*(d-b)-2*(f-d),k=b-d,l=(-j+w.sqrt(j*j-4*i*k))/2/i,n=(-j-w.sqrt(j*j-4*i*k))/2/i,z(l)>"1e12"&&(l=.5),z(n)>"1e12"&&(n=.5),l>0&&l<1&&(q=bP(a,b,c,d,e,f,g,h,l),p.push(q.x),o.push(q.y)),n>0&&n<1&&(q=bP(a,b,c,d,e,f,g,h,n),p.push(q.x),o.push(q.y));return{min:{x:y[m](0,p),y:y[m](0,o)},max:{x:x[m](0,p),y:x[m](0,o)}}}),bR=a._path2curve=bv(function(a,b){var c=!b&&bz(a);if(!b&&c.curve)return bJ(c.curve);var d=bL(a),e=b&&bL(b),f={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},g={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},h=function(a,b){var c,d;if(!a)return["C",b.x,b.y,b.x,b.y,b.x,b.y];!(a[0]in{T:1,Q:1})&&(b.qx=b.qy=null);switch(a[0]){case"M":b.X=a[1],b.Y=a[2];break;case"A":a=["C"][n](bO[m](0,[b.x,b.y][n](a.slice(1))));break;case"S":c=b.x+(b.x-(b.bx||b.x)),d=b.y+(b.y-(b.by||b.y)),a=["C",c,d][n](a.slice(1));break;case"T":b.qx=b.x+(b.x-(b.qx||b.x)),b.qy=b.y+(b.y-(b.qy||b.y)),a=["C"][n](bN(b.x,b.y,b.qx,b.qy,a[1],a[2]));break;case"Q":b.qx=a[1],b.qy=a[2],a=["C"][n](bN(b.x,b.y,a[1],a[2],a[3],a[4]));break;case"L":a=["C"][n](bM(b.x,b.y,a[1],a[2]));break;case"H":a=["C"][n](bM(b.x,b.y,a[1],b.y));break;case"V":a=["C"][n](bM(b.x,b.y,b.x,a[1]));break;case"Z":a=["C"][n](bM(b.x,b.y,b.X,b.Y))}return a},i=function(a,b){if(a[b].length>7){a[b].shift();var c=a[b];while(c.length)a.splice(b++,0,["C"][n](c.splice(0,6)));a.splice(b,1),l=x(d.length,e&&e.length||0)}},j=function(a,b,c,f,g){a&&b&&a[g][0]=="M"&&b[g][0]!="M"&&(b.splice(g,0,["M",f.x,f.y]),c.bx=0,c.by=0,c.x=a[g][1],c.y=a[g][2],l=x(d.length,e&&e.length||0))};for(var k=0,l=x(d.length,e&&e.length||0);ke){if(c&&!l.start){m=cs(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n),k+=["C"+m.start.x,m.start.y,m.m.x,m.m.y,m.x,m.y];if(f)return k;l.start=k,k=["M"+m.x,m.y+"C"+m.n.x,m.n.y,m.end.x,m.end.y,i[5],i[6]].join(),n+=j,g=+i[5],h=+i[6];continue}if(!b&&!c){m=cs(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n);return{x:m.x,y:m.y,alpha:m.alpha}}}n+=j,g=+i[5],h=+i[6]}k+=i.shift()+i}l.end=k,m=b?n:c?l:a.findDotsAtSegment(g,h,i[0],i[1],i[2],i[3],i[4],i[5],1),m.alpha&&(m={x:m.x,y:m.y,alpha:m.alpha});return m}},cu=ct(1),cv=ct(),cw=ct(0,1);a.getTotalLength=cu,a.getPointAtLength=cv,a.getSubpath=function(a,b,c){if(this.getTotalLength(a)-c<1e-6)return cw(a,b).end;var d=cw(a,c,1);return b?cw(d,b).end:d},cl.getTotalLength=function(){if(this.type=="path"){if(this.node.getTotalLength)return this.node.getTotalLength();return cu(this.attrs.path)}},cl.getPointAtLength=function(a){if(this.type=="path")return cv(this.attrs.path,a)},cl.getSubpath=function(b,c){if(this.type=="path")return a.getSubpath(this.attrs.path,b,c)};var cx=a.easing_formulas={linear:function(a){return a},"<":function(a){return A(a,1.7)},">":function(a){return A(a,.48)},"<>":function(a){var b=.48-a/1.04,c=w.sqrt(.1734+b*b),d=c-b,e=A(z(d),1/3)*(d<0?-1:1),f=-c-b,g=A(z(f),1/3)*(f<0?-1:1),h=e+g+.5;return(1-h)*3*h*h+h*h*h},backIn:function(a){var b=1.70158;return a*a*((b+1)*a-b)},backOut:function(a){a=a-1;var b=1.70158;return a*a*((b+1)*a+b)+1},elastic:function(a){if(a==!!a)return a;return A(2,-10*a)*w.sin((a-.075)*2*B/.3)+1},bounce:function(a){var b=7.5625,c=2.75,d;a<1/c?d=b*a*a:a<2/c?(a-=1.5/c,d=b*a*a+.75):a<2.5/c?(a-=2.25/c,d=b*a*a+.9375):(a-=2.625/c,d=b*a*a+.984375);return d}};cx.easeIn=cx["ease-in"]=cx["<"],cx.easeOut=cx["ease-out"]=cx[">"],cx.easeInOut=cx["ease-in-out"]=cx["<>"],cx["back-in"]=cx.backIn,cx["back-out"]=cx.backOut;var cy=[],cz=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(a){setTimeout(a,16)},cA=function(){var b=+(new Date),c=0;for(;c1&&!d.next){for(s in k)k[g](s)&&(r[s]=d.totalOrigin[s]);d.el.attr(r),cE(d.anim,d.el,d.anim.percents[0],null,d.totalOrigin,d.repeat-1)}d.next&&!d.stop&&cE(d.anim,d.el,d.next,null,d.totalOrigin,d.repeat)}}a.svg&&m&&m.paper&&m.paper.safari(),cy.length&&cz(cA)},cB=function(a){return a>255?255:a<0?0:a};cl.animateWith=function(b,c,d,e,f,g){var h=this;if(h.removed){g&&g.call(h);return h}var i=d instanceof cD?d:a.animation(d,e,f,g),j,k;cE(i,h,i.percents[0],null,h.attr());for(var l=0,m=cy.length;l.5)*2-1;i(m-.5,2)+i(n-.5,2)>.25&&(n=f.sqrt(.25-i(m-.5,2))*e+.5)&&n!=.5&&(n=n.toFixed(5)-1e-5*e)}return l}),e=e.split(/\s*\-\s*/);if(j=="linear"){var t=e.shift();t=-d(t);if(isNaN(t))return null;var u=[0,0,f.cos(a.rad(t)),f.sin(a.rad(t))],v=1/(g(h(u[2]),h(u[3]))||1);u[2]*=v,u[3]*=v,u[2]<0&&(u[0]=-u[2],u[2]=0),u[3]<0&&(u[1]=-u[3],u[3]=0)}var w=a._parseDots(e);if(!w)return null;k=k.replace(/[\(\)\s,\xb0#]/g,"_"),b.gradient&&k!=b.gradient.id&&(p.defs.removeChild(b.gradient),delete b.gradient);if(!b.gradient){s=q(j+"Gradient",{id:k}),b.gradient=s,q(s,j=="radial"?{fx:m,fy:n}:{x1:u[0],y1:u[1],x2:u[2],y2:u[3],gradientTransform:b.matrix.invert()}),p.defs.appendChild(s);for(var x=0,y=w.length;x1?G.opacity/100:G.opacity});case"stroke":G=a.getRGB(p),i.setAttribute(o,G.hex),o=="stroke"&&G[b]("opacity")&&q(i,{"stroke-opacity":G.opacity>1?G.opacity/100:G.opacity}),o=="stroke"&&d._.arrows&&("startString"in d._.arrows&&t(d,d._.arrows.startString),"endString"in d._.arrows&&t(d,d._.arrows.endString,1));break;case"gradient":(d.type=="circle"||d.type=="ellipse"||c(p).charAt()!="r")&&r(d,p);break;case"opacity":k.gradient&&!k[b]("stroke-opacity")&&q(i,{"stroke-opacity":p>1?p/100:p});case"fill-opacity":if(k.gradient){H=a._g.doc.getElementById(i.getAttribute("fill").replace(/^url\(#|\)$/g,l)),H&&(I=H.getElementsByTagName("stop"),q(I[I.length-1],{"stop-opacity":p}));break};default:o=="font-size"&&(p=e(p,10)+"px");var J=o.replace(/(\-.)/g,function(a){return a.substring(1).toUpperCase()});i.style[J]=p,d._.dirty=1,i.setAttribute(o,p)}}y(d,f),i.style.visibility=m},x=1.2,y=function(d,f){if(d.type=="text"&&!!(f[b]("text")||f[b]("font")||f[b]("font-size")||f[b]("x")||f[b]("y"))){var g=d.attrs,h=d.node,i=h.firstChild?e(a._g.doc.defaultView.getComputedStyle(h.firstChild,l).getPropertyValue("font-size"),10):10;if(f[b]("text")){g.text=f.text;while(h.firstChild)h.removeChild(h.firstChild);var j=c(f.text).split("\n"),k=[],m;for(var n=0,o=j.length;n"));var $=X.getBoundingClientRect();t.W=m.w=($.right-$.left)/Y,t.H=m.h=($.bottom-$.top)/Y,t.X=m.x,t.Y=m.y+t.H/2,("x"in i||"y"in i)&&(t.path.v=a.format("m{0},{1}l{2},{1}",f(m.x*u),f(m.y*u),f(m.x*u)+1));var _=["x","y","text","font","font-family","font-weight","font-style","font-size"];for(var ba=0,bb=_.length;ba.25&&(c=e.sqrt(.25-i(b-.5,2))*((c>.5)*2-1)+.5),m=b+n+c);return o}),f=f.split(/\s*\-\s*/);if(l=="linear"){var p=f.shift();p=-d(p);if(isNaN(p))return null}var q=a._parseDots(f);if(!q)return null;b=b.shape||b.node;if(q.length){b.removeChild(g),g.on=!0,g.method="none",g.color=q[0].color,g.color2=q[q.length-1].color;var r=[];for(var s=0,t=q.length;s')}}catch(c){F=function(a){return b.createElement("<"+a+' xmlns="urn:schemas-microsoft.com:vml" class="rvml">')}}},a._engine.initWin(a._g.win),a._engine.create=function(){var b=a._getContainer.apply(0,arguments),c=b.container,d=b.height,e,f=b.width,g=b.x,h=b.y;if(!c)throw new Error("VML container not found.");var i=new a._Paper,j=i.canvas=a._g.doc.createElement("div"),k=j.style;g=g||0,h=h||0,f=f||512,d=d||342,i.width=f,i.height=d,f==+f&&(f+="px"),d==+d&&(d+="px"),i.coordsize=u*1e3+n+u*1e3,i.coordorigin="0 0",i.span=a._g.doc.createElement("span"),i.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;",j.appendChild(i.span),k.cssText=a.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden",f,d),c==1?(a._g.doc.body.appendChild(j),k.left=g+"px",k.top=h+"px",k.position="absolute"):c.firstChild?c.insertBefore(j,c.firstChild):c.appendChild(j),i.renderfix=function(){};return i},a.prototype.clear=function(){a.eve("raphael.clear",this),this.canvas.innerHTML=o,this.span=a._g.doc.createElement("span"),this.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;",this.canvas.appendChild(this.span),this.bottom=this.top=null},a.prototype.remove=function(){a.eve("raphael.remove",this),this.canvas.parentNode.removeChild(this.canvas);for(var b in this)this[b]=typeof this[b]=="function"?a._removedFactory(b):null;return!0};var G=a.st;for(var H in E)E[b](H)&&!G[b](H)&&(G[H]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a].apply(c,b)})}}(H))}(window.Raphael) \ No newline at end of file diff --git a/lib/underscore-min.js b/lib/underscore-min.js deleted file mode 100644 index 5a0cb3b0..00000000 --- a/lib/underscore-min.js +++ /dev/null @@ -1,32 +0,0 @@ -// Underscore.js 1.3.3 -// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. -// Underscore is freely distributable under the MIT license. -// Portions of Underscore are inspired or borrowed from Prototype, -// Oliver Steele's Functional, and John Resig's Micro-Templating. -// For all details and documentation: -// http://documentcloud.github.com/underscore -(function(){function r(a,c,d){if(a===c)return 0!==a||1/a==1/c;if(null==a||null==c)return a===c;a._chain&&(a=a._wrapped);c._chain&&(c=c._wrapped);if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return!1;switch(e){case "[object String]":return a==""+c;case "[object Number]":return a!=+a?c!=+c:0==a?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source== -c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if("object"!=typeof a||"object"!=typeof c)return!1;for(var f=d.length;f--;)if(d[f]==a)return!0;d.push(a);var f=0,g=!0;if("[object Array]"==e){if(f=a.length,g=f==c.length)for(;f--&&(g=f in a==f in c&&r(a[f],c[f],d)););}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return!1;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&r(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c,h)&&!f--)break; -g=!f}}d.pop();return g}var s=this,I=s._,o={},k=Array.prototype,p=Object.prototype,i=k.slice,J=k.unshift,l=p.toString,K=p.hasOwnProperty,y=k.forEach,z=k.map,A=k.reduce,B=k.reduceRight,C=k.filter,D=k.every,E=k.some,q=k.indexOf,F=k.lastIndexOf,p=Array.isArray,L=Object.keys,t=Function.prototype.bind,b=function(a){return new m(a)};"undefined"!==typeof exports?("undefined"!==typeof module&&module.exports&&(exports=module.exports=b),exports._=b):s._=b;b.VERSION="1.3.3";var j=b.each=b.forEach=function(a, -c,d){if(a!=null)if(y&&a.forEach===y)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e2;a==null&&(a=[]);if(A&& -a.reduce===A){e&&(c=b.bind(c,e));return f?a.reduce(c,d):a.reduce(c)}j(a,function(a,b,i){if(f)d=c.call(e,d,a,b,i);else{d=a;f=true}});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(B&&a.reduceRight===B){e&&(c=b.bind(c,e));return f?a.reduceRight(c,d):a.reduceRight(c)}var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect=function(a, -c,b){var e;G(a,function(a,g,h){if(c.call(b,a,g,h)){e=a;return true}});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(C&&a.filter===C)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(D&&a.every===D)return a.every(c,b);j(a,function(a,g,h){if(!(e=e&&c.call(b, -a,g,h)))return o});return!!e};var G=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(E&&a.some===E)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return o});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;if(q&&a.indexOf===q)return a.indexOf(c)!=-1;return b=G(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck= -function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a)&&a[0]===+a[0])return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a)&&a[0]===+a[0])return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;bd?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]}; -j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a,c,d){d||(d=b.identity);for(var e=0,f=a.length;e>1;d(a[g])=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1),true);return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a= -i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e=0;d--)b=[a[d].apply(this,b)];return b[0]}};b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=L||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&& -c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.pick=function(a){var c={};j(b.flatten(i.call(arguments,1)),function(b){b in a&&(c[b]=a[b])});return c};b.defaults=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return r(a,b,[])};b.isEmpty= -function(a){if(a==null)return true;if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=p||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};b.isArguments=function(a){return l.call(a)=="[object Arguments]"};b.isArguments(arguments)||(b.isArguments=function(a){return!(!a||!b.has(a,"callee"))});b.isFunction=function(a){return l.call(a)=="[object Function]"}; -b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isFinite=function(a){return b.isNumber(a)&&isFinite(a)};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a, -b){return K.call(a,b)};b.noConflict=function(){s._=I;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.result=function(a,c){if(a==null)return null;var d=a[c];return b.isFunction(d)?d.call(a):d};b.mixin=function(a){j(b.functions(a),function(c){M(c,b[c]=a[c])})};var N=0;b.uniqueId= -function(a){var b=N++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var u=/.^/,n={"\\":"\\","'":"'",r:"\r",n:"\n",t:"\t",u2028:"\u2028",u2029:"\u2029"},v;for(v in n)n[n[v]]=v;var O=/\\|'|\r|\n|\t|\u2028|\u2029/g,P=/\\(\\|'|r|n|t|u2028|u2029)/g,w=function(a){return a.replace(P,function(a,b){return n[b]})};b.template=function(a,c,d){d=b.defaults(d||{},b.templateSettings);a="__p+='"+a.replace(O,function(a){return"\\"+n[a]}).replace(d.escape|| -u,function(a,b){return"'+\n_.escape("+w(b)+")+\n'"}).replace(d.interpolate||u,function(a,b){return"'+\n("+w(b)+")+\n'"}).replace(d.evaluate||u,function(a,b){return"';\n"+w(b)+"\n;__p+='"})+"';\n";d.variable||(a="with(obj||{}){\n"+a+"}\n");var a="var __p='';var print=function(){__p+=Array.prototype.join.call(arguments, '')};\n"+a+"return __p;\n",e=new Function(d.variable||"obj","_",a);if(c)return e(c,b);c=function(a){return e.call(this,a,b)};c.source="function("+(d.variable||"obj")+"){\n"+a+"}";return c}; -b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var x=function(a,c){return c?b(a).chain():a},M=function(a,c){m.prototype[a]=function(){var a=i.call(arguments);J.call(a,this._wrapped);return x(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return x(d, -this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return x(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain=true;return this};m.prototype.value=function(){return this._wrapped}}).call(this); diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json deleted file mode 100644 index 007fdc21..00000000 --- a/npm-shrinkwrap.json +++ /dev/null @@ -1,264 +0,0 @@ -{ - "name": "LearnGitBranching", - "version": "0.8.0", - "dependencies": { - "backbone": { - "version": "1.1.2", - "from": "backbone@*", - "resolved": "https://registry.npmjs.org/backbone/-/backbone-1.1.2.tgz", - "dependencies": { - "underscore": { - "version": "1.8.3", - "from": "underscore@>=1.5.0", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz" - } - } - }, - "events": { - "version": "1.0.2", - "from": "events@*", - "resolved": "https://registry.npmjs.org/events/-/events-1.0.2.tgz" - }, - "flux": { - "version": "2.0.1", - "from": "flux@*", - "resolved": "https://registry.npmjs.org/flux/-/flux-2.0.1.tgz" - }, - "jquery": { - "version": "1.7.3", - "from": "jquery@~1.7.3", - "dependencies": { - "jsdom": { - "version": "0.2.19", - "from": "jsdom@~0.2.14", - "dependencies": { - "request": { - "version": "2.30.0", - "from": "request@2.x", - "dependencies": { - "qs": { - "version": "0.6.6", - "from": "qs@~0.6.0" - }, - "json-stringify-safe": { - "version": "5.0.0", - "from": "json-stringify-safe@~5.0.0" - }, - "forever-agent": { - "version": "0.5.0", - "from": "forever-agent@~0.5.0" - }, - "node-uuid": { - "version": "1.4.1", - "from": "node-uuid@~1.4.0" - }, - "mime": { - "version": "1.2.11", - "from": "mime@~1.2.9" - }, - "tough-cookie": { - "version": "0.9.15", - "from": "tough-cookie@~0.9.15", - "dependencies": { - "punycode": { - "version": "1.2.3", - "from": "punycode@>=0.2.0" - } - } - }, - "form-data": { - "version": "0.1.2", - "from": "form-data@~0.1.0", - "dependencies": { - "combined-stream": { - "version": "0.0.4", - "from": "combined-stream@~0.0.4", - "dependencies": { - "delayed-stream": { - "version": "0.0.5", - "from": "delayed-stream@0.0.5" - } - } - }, - "async": { - "version": "0.2.9", - "from": "async@~0.2.9" - } - } - }, - "tunnel-agent": { - "version": "0.3.0", - "from": "tunnel-agent@~0.3.0" - }, - "http-signature": { - "version": "0.10.0", - "from": "http-signature@~0.10.0", - "dependencies": { - "assert-plus": { - "version": "0.1.2", - "from": "assert-plus@0.1.2" - }, - "asn1": { - "version": "0.1.11", - "from": "asn1@0.1.11" - }, - "ctype": { - "version": "0.5.2", - "from": "ctype@0.5.2" - } - } - }, - "oauth-sign": { - "version": "0.3.0", - "from": "oauth-sign@~0.3.0" - }, - "hawk": { - "version": "1.0.0", - "from": "hawk@~1.0.0", - "dependencies": { - "hoek": { - "version": "0.9.1", - "from": "hoek@0.9.x" - }, - "boom": { - "version": "0.4.2", - "from": "boom@0.4.x" - }, - "cryptiles": { - "version": "0.2.2", - "from": "cryptiles@0.2.x" - }, - "sntp": { - "version": "0.2.4", - "from": "sntp@0.2.x" - } - } - }, - "aws-sign2": { - "version": "0.5.0", - "from": "aws-sign2@~0.5.0" - } - } - }, - "cssom": { - "version": "0.2.5", - "from": "cssom@0.2.x" - }, - "cssstyle": { - "version": "0.2.9", - "from": "cssstyle@>=0.2.3", - "dependencies": { - "cssom": { - "version": "0.3.0", - "from": "cssom@0.3.x" - } - } - }, - "contextify": { - "version": "0.1.6", - "from": "contextify@0.1.x", - "dependencies": { - "bindings": { - "version": "1.1.1", - "from": "bindings@*" - } - } - } - } - }, - "htmlparser": { - "version": "1.7.6", - "from": "htmlparser@1.7.6" - }, - "xmlhttprequest": { - "version": "1.4.2", - "from": "xmlhttprequest@~1.4.2" - }, - "location": { - "version": "0.0.1", - "from": "location@0.0.1" - }, - "navigator": { - "version": "1.0.1", - "from": "navigator@~1.0.1" - } - } - }, - "markdown": { - "version": "0.4.0", - "from": "markdown@~0.4.0", - "dependencies": { - "nopt": { - "version": "1.0.10", - "from": "nopt@1", - "dependencies": { - "abbrev": { - "version": "1.0.4", - "from": "abbrev@1" - } - } - } - } - }, - "object-assign": { - "version": "2.0.0", - "from": "object-assign@*", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.0.0.tgz" - }, - "q": { - "version": "0.8.12", - "from": "q@~0.8.11" - }, - "react": { - "version": "0.13.1", - "from": "react@*", - "resolved": "https://registry.npmjs.org/react/-/react-0.13.1.tgz", - "dependencies": { - "envify": { - "version": "3.4.0", - "from": "envify@>=3.0.0 <4.0.0", - "resolved": "https://registry.npmjs.org/envify/-/envify-3.4.0.tgz", - "dependencies": { - "through": { - "version": "2.3.6", - "from": "through@>=2.3.4 <2.4.0", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.6.tgz" - }, - "jstransform": { - "version": "10.1.0", - "from": "jstransform@>=10.0.1 <11.0.0", - "resolved": "https://registry.npmjs.org/jstransform/-/jstransform-10.1.0.tgz", - "dependencies": { - "base62": { - "version": "0.1.1", - "from": "base62@0.1.1", - "resolved": "https://registry.npmjs.org/base62/-/base62-0.1.1.tgz" - }, - "esprima-fb": { - "version": "13001.1001.0-dev-harmony-fb", - "from": "esprima-fb@13001.1001.0-dev-harmony-fb", - "resolved": "https://registry.npmjs.org/esprima-fb/-/esprima-fb-13001.1001.0-dev-harmony-fb.tgz" - }, - "source-map": { - "version": "0.1.31", - "from": "source-map@0.1.31", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.31.tgz", - "dependencies": { - "amdefine": { - "version": "0.1.0", - "from": "amdefine@>=0.0.4" - } - } - } - } - } - } - } - } - }, - "underscore": { - "version": "1.4.4", - "from": "underscore@~1.4.3" - } - } -} diff --git a/package.json b/package.json index 85e723ef..46ec0868 100644 --- a/package.json +++ b/package.json @@ -1,41 +1,52 @@ { "name": "LearnGitBranching", "version": "0.8.0", + "description": "An interactive git visualization to challenge and educate!", + "homepage": "https://learngitbranching.js.org", + "author": "Peter Cottle ", "license": "MIT", "scripts": { - "test": "grunt test" + "test": "gulp test" }, "repository": { "type": "git", "url": "https://github.com/pcottle/learnGitBranching" }, "devDependencies": { - "browserify": "^13.0.0", - "grunt": "~0.4.2", - "grunt-browserify": "^4.0.1", - "grunt-cli": "~0.1.11", - "grunt-contrib-clean": "~0.5.0", - "grunt-contrib-jshint": "~0.7.2", - "grunt-contrib-uglify": "~0.2.7", - "grunt-env": "^0.4.4", - "grunt-hash": "~0.5.0", - "grunt-jasmine-node": "~0.1.0", - "grunt-jsxhint": "^0.5.0", - "grunt-react": "^0.12.1", - "grunt-shell-spawn": "~0.3.0", - "jasmine-node": "~1.12.0", + "@babel/core": "^7.4.8", + "@babel/preset-react": "^7.0.0", + "babelify": "^10.0.0", + "browserify": "^16.5.0", + "contributor-faces": "^1.0.2", + "fancy-log": "^1.3.3", + "glob": "^7.1.6", + "gulp": "^4.0.2", + "gulp-clean": "^0.4.0", + "gulp-clean-css": "^4.3.0", + "gulp-concat": "^2.6.1", + "gulp-hash": "^4.2.2", + "gulp-jasmine": "^4.0.0", + "gulp-jshint": "^2.1.0", + "gulp-terser": "^1.2.0", + "gulp-uglify": "^3.0.2", + "html-minifier": "^4.0.0", + "jasmine-spec-reporter": "^4.2.1", + "jshint": "^2.11.0", "prompt": "^1.0.0", - "react-tools": "^0.13.1" + "vinyl-buffer": "^1.0.1", + "vinyl-source-stream": "^2.0.0" }, "dependencies": { - "backbone": "~1.1.2", - "events": "^1.0.2", - "flux": "^2.0.1", - "jquery": "~1.7.3", - "markdown": "~0.4.0", - "object-assign": "^2.0.0", - "q": "~0.8.11", - "react": "^0.13.1", + "backbone": "^1.4.0", + "flux": "^3.1.3", + "jquery": "^3.4.0", + "jquery-ui": "^1.12.1", + "marked": "^1.0.0", + "prop-types": "^15.7.2", + "q": "^1.5.1", + "raphael": "^2.1.0", + "react": "^16.13.0", + "react-dom": "^16.13.0", "underscore": "~1.4.3" } } diff --git a/src/js/actions/GlobalStateActions.js b/src/js/actions/GlobalStateActions.js index f04a747e..4e3ea1ca 100644 --- a/src/js/actions/GlobalStateActions.js +++ b/src/js/actions/GlobalStateActions.js @@ -20,6 +20,12 @@ var GlobalStateActions = { }); }, + disableLevelInstructions: function() { + AppDispatcher.handleViewAction({ + type: ActionTypes.DISABLE_LEVEL_INSTRUCTIONS, + }); + }, + changeFlipTreeY: function(flipTreeY) { AppDispatcher.handleViewAction({ type: ActionTypes.CHANGE_FLIP_TREE_Y, diff --git a/src/js/app/index.js b/src/js/app/index.js index 69e1fdce..683def93 100644 --- a/src/js/app/index.js +++ b/src/js/app/index.js @@ -1,8 +1,9 @@ var Backbone = require('backbone'); +var jQuery = require('jquery'); var EventEmitter = require('events').EventEmitter; var React = require('react'); +var ReactDOM = require('react-dom'); -var assign = require('object-assign'); var util = require('../util'); var intl = require('../intl'); var LocaleStore = require('../stores/LocaleStore'); @@ -11,7 +12,17 @@ var LocaleActions = require('../actions/LocaleActions'); /** * Globals */ -var events = assign( + +Backbone.$ = jQuery; + +// Bypass jasmine +if (util.isBrowser()) { + window.jQuery = jQuery; + window.$ = jQuery; + window.Raphael = require('raphael'); +} + +var events = Object.assign( {}, EventEmitter.prototype, { @@ -21,7 +32,7 @@ var events = assign( } } ); -// Allow unlimited listeners, so FF doesnt break +// Allow unlimited listeners, so FF doesn't break events.setMaxListeners(0); var commandUI; var sandbox; @@ -86,8 +97,28 @@ var vcsModeRefresh = function(eventData) { $('body').toggleClass('hgMode', !isGit); }; +var insertAlternateLinks = function(pageId) { + // For now pageId is null, which would link to the main page. + // In future if pageId is provided this method should link to a specific page + + // The value of the hreflang attribute identifies the language (in ISO 639-1 format) + // and optionally a region (in ISO 3166-1 Alpha 2 format) of an alternate URL + + var altLinks = LocaleStore.getSupportedLocales().map(function(langCode) { + var url = "https://learngitbranching.js.org/?locale=" + langCode; + return ''; + }); + var defaultUrl = "https://learngitbranching.js.org/?locale=" + LocaleStore.getDefaultLocale(); + altLinks.push(''); + $('head').prepend(altLinks); + +}; + var intlRefresh = function() { if (!window.$) { return; } + var countryCode = LocaleStore.getLocale().split("_")[0]; + $("html").attr('lang', countryCode); + $("meta[http-equiv='content-language']").attr("content", countryCode); $('span.intl-aware').each(function(i, el) { var intl = require('../intl'); var key = $(el).attr('data-intl'); @@ -145,7 +176,7 @@ var initRootEvents = function(eventBaton) { var initDemo = function(sandbox) { var params = util.parseQueryString(window.location.href); - // being the smart programmer I am (not), I dont include a true value on demo, so + // being the smart programmer I am (not), I don't include a true value on demo, so // I have to check if the key exists here var commands; if (/(iPhone|iPod|iPad).*AppleWebKit/i.test(navigator.userAgent) || /android/i.test(navigator.userAgent)) { @@ -232,7 +263,7 @@ var initDemo = function(sandbox) { } if (params.hasOwnProperty('STARTREACT')) { /* - React.render( + ReactDOM.render( React.createElement(CommandView, {}), document.getElementById(params['STARTREACT']) );*/ @@ -249,6 +280,8 @@ var initDemo = function(sandbox) { tryLocaleDetect(); } + insertAlternateLinks(); + if (params.command) { var command = unescape(params.command); sandbox.mainVis.customEvents.on('gitEngineReady', function() { @@ -294,11 +327,11 @@ function CommandUI() { el: $('#commandLineBar') }); - React.render( + ReactDOM.render( React.createElement(MainHelperBarView), document.getElementById('helperBarMount') ); - React.render( + ReactDOM.render( React.createElement( CommandHistoryView, { commandCollection: this.commandCollection } @@ -328,4 +361,3 @@ exports.getLevelDropdown = function() { }; exports.init = init; - diff --git a/src/js/commands/index.js b/src/js/commands/index.js index a6045417..995f1ea0 100644 --- a/src/js/commands/index.js +++ b/src/js/commands/index.js @@ -1,4 +1,3 @@ -var _ = require('underscore'); var intl = require('../intl'); var Errors = require('../util/errors'); @@ -16,7 +15,7 @@ var commandConfigs = { var commands = { execute: function(vcs, name, engine, commandObj) { if (!commandConfigs[vcs][name]) { - throw new Error('i dont have a command for ' + name); + throw new Error('i don\'t have a command for ' + name); } var config = commandConfigs[vcs][name]; if (config.delegate) { @@ -34,11 +33,11 @@ var commands = { if (result.multiDelegate) { // we need to do multiple delegations with // a different command at each step - _.each(result.multiDelegate, function(delConfig) { + result.multiDelegate.forEach(function(delConfig) { // copy command, and then set opts commandObj.setOptionsMap(delConfig.options || {}); commandObj.setGeneralArgs(delConfig.args || []); - + commandConfigs[delConfig.vcs][delConfig.name].execute.call(this, engine, commandObj); }, this); } else { @@ -70,7 +69,7 @@ var commands = { var displayName = config.displayName || name; var thisMap = {}; // start all options off as disabled - _.each(config.options, function(option) { + (config.options || []).forEach(function(option) { thisMap[option] = false; }); optionMap[vcs][displayName] = thisMap; @@ -102,8 +101,10 @@ var commands = { }, loop: function(callback, context) { - _.each(commandConfigs, function(commandConfig, vcs) { - _.each(commandConfig, function(config, name) { + Object.keys(commandConfigs).forEach(function(vcs) { + var commandConfig = commandConfigs[vcs]; + Object.keys(commandConfig).forEach(function(name) { + var config = commandConfig[name]; callback(config, name, vcs); }); }); @@ -116,18 +117,21 @@ var parse = function(str) { var options; // see if we support this particular command - _.each(commands.getRegexMap(), function (map, thisVCS) { - _.each(map, function(regex, thisMethod) { + var regexMap = commands.getRegexMap(); + Object.keys(regexMap).forEach(function (thisVCS) { + var map = regexMap[thisVCS]; + Object.keys(map).forEach(function(thisMethod) { + var regex = map[thisMethod]; if (regex.exec(str)) { vcs = thisVCS; method = thisMethod; // every valid regex has to have the parts of // - // because there are always two spaces + // because there are always two space-groups // before our "stuff" we can simply - // split on spaces and grab everything after + // split on space-groups and grab everything after // the second: - options = str.split(' ').slice(2).join(' '); + options = str.match(/('.*?'|".*?"|\S+)/g).slice(2); } }); }); @@ -170,11 +174,8 @@ function CommandOptionParser(vcs, method, options) { } CommandOptionParser.prototype.explodeAndSet = function() { - // TODO -- this is ugly - // split on spaces, except when inside quotes - var exploded = this.rawOptions.match(/('.*?'|".*?"|\S+)/g) || []; - for (var i = 0; i < exploded.length; i++) { - var part = exploded[i]; + for (var i = 0; i < this.rawOptions.length; i++) { + var part = this.rawOptions[i]; if (part.slice(0,1) == '-') { // it's an option, check supportedMap @@ -187,7 +188,7 @@ CommandOptionParser.prototype.explodeAndSet = function() { }); } - var next = exploded[i + 1]; + var next = this.rawOptions[i + 1]; var optionArgs = []; if (next && next.slice(0,1) !== '-') { // only store the next argument as this diff --git a/src/js/constants/AppConstants.js b/src/js/constants/AppConstants.js index b738fbfa..1c8c80bd 100644 --- a/src/js/constants/AppConstants.js +++ b/src/js/constants/AppConstants.js @@ -26,6 +26,7 @@ module.exports = { SUBMIT_COMMAND: null, CHANGE_LOCALE: null, CHANGE_LOCALE_FROM_HEADER: null, + DISABLE_LEVEL_INSTRUCTIONS: null, /** * only dispatched when you actually * solve the level, not ask for solution diff --git a/src/js/constants/AppStyles.js b/src/js/constants/AppStyles.js deleted file mode 100644 index 2d1ef06c..00000000 --- a/src/js/constants/AppStyles.js +++ /dev/null @@ -1,16 +0,0 @@ -var AppStyles = { - blueBackground: '#5cbcfc', - terminalBackground: '#424242', - terminalText: 'rgb(238, 238, 238)', - terminalHeader: '#EFEDEE', - terminalBorder: '#303030', - terminalFontFamily: 'Courier', -}; - -AppStyles.terminalTextStyle = { - color: AppStyles.terminalText, - fontFamily: AppStyles.terminalFontFamily, - fontWeight: 'bold', -}; - -module.exports = AppStyles; diff --git a/src/js/constants/Routes.js b/src/js/constants/Routes.js deleted file mode 100644 index d9af3475..00000000 --- a/src/js/constants/Routes.js +++ /dev/null @@ -1,19 +0,0 @@ -var assign = require('object-assign'); -var keyMirror = require('../util/keyMirror'); - -module.exports = keyMirror({ - NUX: null, - LOADING: null, - SEQUENCE_SELECT: null, - LEVEL_SELECT: null, -}); - -module.exports.getRouteWithParams = function(id, params) { - return assign({id: id}, params); -}; - -module.exports.getRouteForID = function(id) { - return { - id: id, - }; -}; diff --git a/src/js/dialogs/confirmShowSolution.js b/src/js/dialogs/confirmShowSolution.js index 07815bcf..486965a7 100644 --- a/src/js/dialogs/confirmShowSolution.js +++ b/src/js/dialogs/confirmShowSolution.js @@ -49,6 +49,26 @@ exports.dialog = { ] } }], + 'es_MX': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## ¿Estás seguro de que quieres ver la solución?', + '', + '¡Creo en ti! ¡Yo sé que puedes!' + ] + } + }], + 'es_ES': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## ¿Estás seguro de que quieres ver la solución?', + '', + '¡Creo en ti! ¡Ánimo!' + ] + } + }], 'pt_BR': [{ type: 'ModalAlert', options: { @@ -59,13 +79,23 @@ exports.dialog = { ] } }], + 'gl': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## ¿Queres ver a solución?', + '', + 'Seguro que podes, ¡inténtao unha vez máis!' + ] + } + }], 'fr_FR': [{ type: 'ModalAlert', options: { markdowns: [ '## Êtes-vous sûr de vouloir voir la solution ?', '', - 'Je crois en vous ! Vous pouvez le faire' + 'Je crois en vous ! Vous pouvez le faire !' ] } }], @@ -99,11 +129,51 @@ exports.dialog = { type: 'ModalAlert', options: { markdowns: [ - '## Впевнений, що хошеш побачити розв’язок?', + '## Впевнений, що хочеш побачити розв’язок?', '', 'Я вірю в тебе! Ти впораєшся!' ] } - }] + }], + 'vi': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## Bạn chắc là muốn xem đáp án chứ?', + '', + 'Tôi tin ở bạn! Bạn có thể làm được!' + ] + } + }], + 'sl_SI': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## Si prepričan, da hočeš videti rešitev?', + '', + 'Verjamem vate! Maš ti to! Ali pač ne?' + ] + } + }], + 'pl': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## Czy na pewno chcesz zobaczyć rozwiązanie?', + '', + 'Wierzę w Ciebie! Możesz to zrobić' + ] + } + }], + 'ta_IN': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## நீங்கள் நிச்சயமாக தீர்வை காண விரும்புகிறீர்களா?', + '', + 'நான் உங்களால் அதை செய்ய முடியும் என நினைக்கிறேன்!' + ] + } + }], }; diff --git a/src/js/dialogs/levelBuilder.js b/src/js/dialogs/levelBuilder.js index 8ea2f989..2263fba7 100644 --- a/src/js/dialogs/levelBuilder.js +++ b/src/js/dialogs/levelBuilder.js @@ -26,13 +26,13 @@ exports.dialog = { '', 'So funktioniert\'s:', '', - ' * Stelle mit Git-Befehlen die Ausganssituation her', + ' * Stelle mit Git-Befehlen die Ausgangssituation her', ' * Leg den Startpunkt mit ```define start``` fest', ' * Gib eine Abfolge von Git-Befehlen ein, welche die (optimale) Lösung darstellen', ' * Leg den Ziel-Baum mit ```define goal``` fest. Damit markierst du den Endpunkt der Lösung', ' * Gib einen Hinweis mittels ```define hint``` an, wenn du willst', ' * Änder den Namen mittels ```define name```', - ' * Wenn du magst, erstelle einen schönene Einführungsdialog mit ```edit dialog```', + ' * Wenn du magst, erstelle einen schönen Einführungsdialog mit ```edit dialog```', ' * Gib das Kommando ```finish``` ein um deinen Level als JSON auszugeben' ] } @@ -94,6 +94,44 @@ exports.dialog = { ] } }], + 'es_MX': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## ¡Bienvenido al constructor de niveles!', + '', + 'Estos son los pasos principales:', + '', + ' * Preparar el entorno inicial usando comandos de Git', + ' * Definir el árbol inicial con ```define start```', + ' * Introducir la serie de comandos de git que representan la solución óptima', + ' * Crear el árbol objetivo con ```define goal```. El objetivo también determina la solución', + ' * Opcionalmente, crea pistas con ```define hint```', + ' * Dale un nombre con ```define name```', + ' * Opcionalmente, crea un mensaje inicial con ```edit dialog```', + ' * ¡Introduce el comando ```finish``` para obtener tu nivel en formato JSON!' + ] + } + }], + 'es_ES': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## ¡Bienvenido al constructor de niveles!', + '', + 'Estos son los pasos principales:', + '', + ' * Prepara el entorno inicial usando comandos de Git', + ' * Define el árbol inicial con ```define start```', + ' * Introduce la serie de comandos de git que representan la solución óptima', + ' * Crea el árbol objetivo con ```define goal```. El objetivo también determina la solución', + ' * Opcionalmente, crea pistas con ```define hint```', + ' * Dale un nombre con ```define name```', + ' * Opcionalmente, crea un mensaje inicial con ```edit dialog```', + ' * ¡Introduce el comando ```finish``` para obtener tu nivel en formato JSON!' + ] + } + }], 'pt_BR': [{ type: 'ModalAlert', options: { @@ -113,6 +151,25 @@ exports.dialog = { ] } }], + 'gl': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## Benvido ó constructor de niveis!', + '', + 'Estes son os pasos principais:', + '', + ' * Prepara o eido inicial usando comandos de Git', + ' * Define a árbore inicial con ```define start```', + ' * Inserta a secuencia de comandos de git que representan a mellor solución', + ' * Define a árbore obxectivo con ```define goal```. O obxectivo tamén determina a solución', + ' * Opcionalmente, define axudas con ```define hint```', + ' * Dalle un nome con ```define name```', + ' * Opcionalmente, define unha mensaxe inicial con ```edit dialog```', + ' * Escribe o comando ```finish``` para obter seu nivel en formato JSON!' + ] + } + }], 'fr_FR': [{ type: 'ModalAlert', options: { @@ -210,4 +267,80 @@ exports.dialog = { ] } }], + 'vi': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## Chào mừng đến trình tạo cấp độ!', + '', + 'Có những bước chính sau:', + '', + ' * Khởi tạo môi trường với các lệnh git', + ' * Định nghĩa cây để bắt đầu với ```define start```', + ' * Nhập chuỗi lệnh git để tạo đáp án (tốt nhất) của bạn', + ' * Định nghĩa cây mục tiêu với ```define goal```. Định nghĩa mục tiêu đồng thời cũng xác định đáp án', + ' * Có thể định nghĩa gợi ý với ```define hint```', + ' * Chỉnh sửa tên với ```define name```', + ' * Có thể định nghĩa hội thoại bắt đầu với ```edit dialog```', + ' * Nhập lệnh ```finish``` xuất cấp độ của bạn dưới dạng JSON!' + ] + } + }], + 'sl_SI': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## Dobrodošel v graditelju stopenj!', + '', + 'Tu so glavni koraki:', + '', + ' * Postavi začetno stanje z git ukazi', + ' * Določi začetno drevo z ```define start```', + ' * Vnesi zaporedje ukazov, ki predstavljajo (najboljšo) rešitev', + ' * Določi ciljno drevo z ```define goal```. Določanje cilja določi tudi rešitev', + ' * Opcijsko določi namig z ```define hint```', + ' * Uredi ime z ```define name```', + ' * Opcijsko določi ličen začetni dialog z ```edit dialog```', + ' * Vnesi ukaz ```finish``` za ustvarjanje JSON različice tvoje stopnje!' + ] + } + }], + 'pl': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## Witamy w kreatorze poziomów!', + '', + 'Oto główne kroki:', + '', + ' * Przygotuj środowisko początkowe za pomocą poleceń GIT-a', + ' * Zdefiniuj drzewo początkowe za pomocą ```define start```', + ' * Wprowadź serię poleceń GIT-a, które tworzą (optymalne) rozwiązanie', + ' * Utwórz drzewo celów za pomocą ```define goal```. Określenie celu określa również rozwiązanie', + ' * Opcjonalnie utwórz podpowiedzi (wskazówkę) za pomocą ```define hint```', + ' * Nadaj nazwę za pomocą ```define name```', + ' * Opcjonalnie, utwórz wiadomość początkową za pomocą ```edit dialog```', + ' * Wpisz polecenie ```finish```, aby wyświetlić swój poziom w JSON!' + ] + } + }], + 'ta_IN': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## நிலைகளை நிருவகிக்கும் கட்டமைப்பிற்க்கு வருக!', + '', + 'அடிப்படை நடைமுறைகள்:', + '', + ' * முதலாவதாக ஆரம்ப சூழலை git கட்டளைகள் கொன்டுகொன்டு அமைக்கவும்.', + ' * ```define start``` தொடக்க செயல் முறையை வரையறுக்கவும்.', + ' * உகந்த தீர்வினை அடையும் git கட்டளைகளின் தொடரை உள்ளிடவும்.', + ' * ```define goal``` கொண்டு இலக்கினை அடையும் கிழை வரைமுரைகளை தீர்வுடன் அமைக்கவும்.', + ' * தேவை எனில் ```define hint``` கொண்டு உதவி குறிப்பை வரையறுக்கவும்.', + ' * ```define name``` கொண்டு பெயரைத் திருத்தவும்.', + ' * தேவை எனில் ```edit dialog``` கொண்டு ஒரு நல்ல முன்னுறையை வரையறுக்கவும்.', + ' * ```finish``` கொண்டு இந்த நிலையின் JSON!-ஐ அச்சிடுக.' + ] + } + }] }; diff --git a/src/js/dialogs/nextLevel.js b/src/js/dialogs/nextLevel.js index 49d1ebc9..18d48bec 100644 --- a/src/js/dialogs/nextLevel.js +++ b/src/js/dialogs/nextLevel.js @@ -67,6 +67,28 @@ exports.dialog = { ] } }], + 'es_MX': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## ¡Buen trabajo!', + '', + 'Resolviste el nivel en *{numCommands}* comandos; ', + 'nuestra mejor solución usa: {best}.' + ] + } + }], + 'es_ES': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## ¡Buen trabajo!', + '', + 'Resolviste el nivel en *{numCommands}* comandos; ', + 'nuestra mejor solución usa {best}.' + ] + } + }], 'pt_BR': [{ type: 'ModalAlert', options: { @@ -78,6 +100,17 @@ exports.dialog = { ] } }], + 'gl': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## Bo traballo!!', + '', + 'Resolviches o nivel empregando *{numCommands}* comandos; ', + 'a nosa mellor solución é en {best}.' + ] + } + }], 'fr_FR': [{ type: 'ModalAlert', options: { @@ -117,9 +150,53 @@ exports.dialog = { markdowns: [ '## 훌륭합니다!!', '', - '*{numCommands}*개의 명렁으로 레벨을 통과했습니다.; ', + '*{numCommands}*개의 명령으로 레벨을 통과했습니다; ', '모범 답안은 {best}개를 사용합니다.' ] } }], + 'vi': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## Làm tốt lắm!!', + '', + 'Bạn hoàn thành cấp độ này với *{numCommands}* câu lệnh; ', + 'Đáp án của chúng tôi sử dụng {best}.' + ] + } + }], + 'sl_SI': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## Dobro opravljeno!!', + '', + 'Rešil si stopnjo z *{numCommands}* ukazi; ', + 'naša rešitev uporabi {best}.' + ] + } + }], + 'pl': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## Dobra robota!!', + '', + 'Rozwiązałeś poziom używając *{numCommands}* poleceń/ia; ', + 'nasze rozwiązanie składa się z {best}.' + ] + } + }], + 'ta_IN': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## ஆக சிரந்த செயல்!!', + '', + 'நீங்கள் *{numCommands}* நிலைக்கான கட்டளை(கள்) கொண்டு தீர்வை அடிந்து விட்டீர்கள்; ', + 'நமது தீர்வு {best}-ஐ பயன்படுத்து கின்றது.' + ] + } + }], }; diff --git a/src/js/dialogs/sandbox.js b/src/js/dialogs/sandbox.js index bb088acc..908e962d 100644 --- a/src/js/dialogs/sandbox.js +++ b/src/js/dialogs/sandbox.js @@ -18,7 +18,14 @@ exports.dialog = { '', 'PS: Want to go straight to a sandbox next time?', 'Try out ', - '[this special link](https://pcottle.github.io/learnGitBranching/?NODEMO)' + '[this special link](https://pcottle.github.io/learnGitBranching/?NODEMO)', + '', + 'PPS: GitHub (and the industry at large) is moving to naming the default branch as `main` instead of `master` ', + 'with [more details available here](https://github.com/github/renaming). In order to accommodate this change in ', + 'a backwards-compatible way, these two names will be considered aliases of each other, with `main` being ', + 'the preferred one to display. We\'ve made a best-effort attempt to update all of the level content, but ', + 'there will be a long-tail of areas we have missed. Please submit a PR (or open an issue) if you spot any ', + 'egregious ones, and thanks for helping move away from biased terminology.' ] } }], @@ -28,7 +35,7 @@ exports.dialog = { markdowns: [ '## ¡Bienvenid@ a Learn Git Branching!', '', - 'Esta aplicación está diseñada para ayudar a los principantes ', + 'Esta aplicación está diseñada para ayudar a los principiantes ', 'a manejar los poderosos conceptos que hay detrás del trabajo ', 'con ramas (branches) en Git. Esperamos que disfrutes la aplicación ', 'y tal vez incluso ¡que aprendas algo! ', @@ -78,6 +85,118 @@ exports.dialog = { ] } }], + 'es_MX': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## ¡Bienvenid@ a Learn Git Branching!', + '', + 'Esta aplicación está diseñada para ayudar a los principiantes', + 'a manejar los poderosos conceptos que hay detrás del trabajo', + 'con ramas (branches) en Git. Esperamos que disfrutes la aplicación', + 'y tal vez incluso ¡que aprendas algo!', + '', + '# ¡Demo!', + '', + 'Si no viste la demo, mirala en ésta dirección:', + '', + '[https://pcottle.github.io/learnGitBranching/?demo](https://pcottle.github.io/learnGitBranching/?demo)', + '', + '¿Harto de este mensaje? Agregale `?NODEMO` a la URL para dejar de verlo, como en éste link:', + '', + '[https://pcottle.github.io/learnGitBranching/?NODEMO](?NODEMO)' + ] + } + }, { + type: 'ModalAlert', + options: { + markdowns: [ + '## Comandos de git', + '', + 'Tienes una gran variedad de comandos de git en este sandbox. He aquí una lista de los incluidos:', + '', + ' * commit', + ' * branch', + ' * checkout', + ' * cherry-pick', + ' * reset', + ' * revert', + ' * rebase', + ' * merge' + ] + } + }, { + type: 'ModalAlert', + options: { + markdowns: [ + '## ¡Comparte!', + '', + 'Comparte tus árboles con tus amigos usando `export tree` e `import tree`', + '', + '¿Tienes una buena lección que compartir? Prueba construyendo un nivel con `build level` o prueba el nivel de un amigo con `import level`', + '', + 'Para ver todos los comandos disponibles, prueba `show commands`. Hay algunos muy prácticos como `undo` y `reset`', + '', + 'Por ahora, arranquemos con los `levels`...' + ] + } + }], + 'es_ES': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## ¡Bienvenid@ a Learn Git Branching!', + '', + 'Esta aplicación está diseñada para ayudar a los principiantes ', + 'a manejar los poderosos conceptos que hay detrás del trabajo ', + 'con ramas (branches) en Git. Esperamos que disfrutes la aplicación ', + 'y tal vez incluso ¡que aprendas algo! ', + '', + '# ¡Demo!', + '', + 'Si no viste la demo, mírala en esta dirección:', + '', + '[https://pcottle.github.io/learnGitBranching/?demo](https://pcottle.github.io/learnGitBranching/?demo)', + '', + '¿Harto de este mensaje? Agrégale `?NODEMO` a la URL para dejar de verlo, como en este link:', + '', + '[https://pcottle.github.io/learnGitBranching/?NODEMO](?NODEMO)' + ] + } + }, { + type: 'ModalAlert', + options: { + markdowns: [ + '## Comandos de Git', + '', + 'Tienes una gran variedad de comandos de git en este sandbox. Estos incluyen: ', + '', + ' * commit', + ' * branch', + ' * checkout', + ' * cherry-pick', + ' * reset', + ' * revert', + ' * rebase', + ' * merge' + ] + } + }, { + type: 'ModalAlert', + options: { + markdowns: [ + '## ¡Comparte!', + '', + 'Comparte tus árboles con tus amigos usando `export tree` e `import tree`', + '', + '¿Tienes una buena lección que compartir? Prueba construyendo un nivel con `build level` o prueba el nivel de un amigo con `import level`', + '', + 'Para ver todos los comandos disponibles, escribe `show commands`. Hay algunas joyitas como `undo` y `reset`', + '', + 'Por ahora, empecemos con los `levels`...' + ] + } + }], 'pt_BR': [{ type: 'ModalAlert', options: { @@ -134,6 +253,62 @@ exports.dialog = { ] } }], + 'gl': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## Benvido a Learn Git Branching!', + '', + 'Esta aplicación foi desenvolvida para axudar os iniciados en git a ', + 'aprender os poderosos conceptos que hai por detrás do branching con ', + ' git. Agardamos que disfrutes desta aplicación, e tal vez, ', + 'ata aprendas algunha cousa!', + '', + '# Demostracións!', + '', + 'Se aínda non viches a demo, olla aquí:', + '', + '[https://pcottle.github.io/learnGitBranching/?demo](https://pcottle.github.io/learnGitBranching/?demo)', + '', + '¿Farto destas mensaxes? Engade `?NODEMO` á dirección para librarte dela, como no link de abaixo:', + '', + '[https://pcottle.github.io/learnGitBranching/?NODEMO](?NODEMO)' + ] + } + }, { + type: 'ModalAlert', + options: { + markdowns: [ + '## Comandos de git', + '', + 'Tes a túa disposición unha caixa de área con unha variedade de comandos de git:', + '', + ' * commit', + ' * branch', + ' * checkout', + ' * cherry-pick', + ' * reset', + ' * revert', + ' * rebase', + ' * merge' + ] + } + }, { + type: 'ModalAlert', + options: { + markdowns: [ + '## Compartir e importar!', + '', + 'Comparte árbores cos seus amigas con `export tree` e `import tree`', + '', + '¿Tes un enlace moi grande para compartir? Intenta construír un nivel con `build level` ou importe o nivel dun amigo con `import level`', + '', + 'Para ver tódolos comandos, usa `show commands`. Hai algunha xoia como `undo` e `reset`', + '', + 'Por agora, imos comezar cos `levels`...' + ] + } + }], 'de_DE': [{ type: 'ModalAlert', options: { @@ -396,7 +571,7 @@ exports.dialog = { markdowns: [ '## Commandes Git', '', - 'Il existe une large variété de commandes git disponibles dans le mode bac à sable. Sont inclues :', + 'Il existe une large variété de commandes git disponibles dans le mode bac à sable. Sont incluses :', '', ' * commit', ' * branch', @@ -501,5 +676,141 @@ exports.dialog = { '[це спеціальне посилання.](https://pcottle.github.io/learnGitBranching/?NODEMO)' ] } - }] + }], + 'vi': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## Chào mừng đến với Học Nhánh Git', + '', + 'Bạn có hứng thú học Git? Bạn đến đúng nơi rồi đấy! ', + '"Học Nhánh Git" là cách trực quan và hiệu quả nhất để học Git trên web; ', + 'thông qua một loạt các thử thách cấp độ thú vị, bạn sẽ từng bước tìm hiểu sức mạnh của git', + '', + 'Sau khi hội thoại này đóng lại, bạn sẽ thấy nhiều cấp độ mà chúng tôi cung cấp. ', + 'Nếu bạn là người mới thì hãy bắt đầu từ bài đầu tiên. Nếu bạn đã có hiểu biết cơ bản về git, ', + 'hãy thử những bài mang tính thách thức hơn phía sau.', + '', + 'Bạn có thể dùng lệnh `show commands` để xem tất cả các lệnh hiện hữu.', + '', + 'Ghi chú: Nếu muốn trực tiếp vào hộp cát ở lần sau?', + 'Hãy dùng', + '[đường link đặc biệt này của chúng tôi](https://pcottle.github.io/learnGitBranching/?NODEMO)' + ] + } + }], + 'sl_SI': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## Dobrodošel na učenju Git Branchanja', + '', + 'Bi se rad naučil Git? No, prišel si na pravo mesto! ', + '"Learn Git Branching" je najbolj vizualen in interaktiven način učenja Git-a ', + 'na spletu; zagrizel boš v zanimive stopnje, po korakih boš spoznaval osupljive ', + 'funkcije in kaj pa veš, morda ti bo celo zabavno. ;)', + '', + 'Za tem oknom boš videl kopico stopenj, ki so na razpolago. Če si ', + 'začetnik, kar pogumno, začni s prvo. Če pa že poznaš Git osnove, ', + 'se preizkusi v zahtevnejših stopnjah.', + '', + 'Vidiš lahko vse ukaze, ki so na voljo, z ukazom `show commands` v terminalu.', + '', + 'PS: Bi šel rad naslednjič naravnost v peskovnik?', + 'Poizkusi s', + '[to posebno povezavo](https://pcottle.github.io/learnGitBranching/?NODEMO)' + ] + } + }], + 'pl': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## Witaj w Learn Git Branching!', + '', + 'Celem tej aplikacji jest zilustrowanie rozległych i złożonych relacji pomiędzy procesami związanymi z pracą z GIT-em.', + 'Mam nadzieję, że ci się to spodoba i może nawet się czegoś nauczysz!', + '"Learn Git Branching" to najbardziej wizualny i interaktywny sposób na naukę GIT-a w sieci.', + 'Będziesz miał do czynienia z ekscytującymi poziomami wraz z pokazaniem krok po kroku potężnych funkcji, a może nawet z odrobiną zabawy po drodze.', + '', + 'Jeśli jesteś początkujący, po prostu zacznij od pierwszego poziomu.', + 'Jeśli znasz już podstawy GIT-a, wypróbuj niektóre z naszych późniejszych, bardziej wymagających poziomów.', + '', + '# Demo!', + '', + 'Jeśli nie widziałeś tej demonstracji, możesz ją obejrzeć tutaj:', + '', + '[https://pcottle.github.io/learnGitBranching/?demo](https://pcottle.github.io/learnGitBranching/?demo)', + '', + 'Masz dość tego okna? Dodaj `?NODEMO` do adresu URL, aby się go pozbyć, w ten sposób:', + '', + '[https://pcottle.github.io/learnGitBranching/?NODEMO](?NODEMO)' + ] + } + }, { + type: 'ModalAlert', + options: { + markdowns: [ + '## Komendy GIT-a', + '', + 'W trybie piaskownicy dostępna jest duża liczba poleceń GIT. Między innymi', + '', + ' * commit', + ' * branch', + ' * checkout', + ' * cherry-pick', + ' * reset', + ' * revert', + ' * rebase', + ' * merge' + ] + } + }, { + type: 'ModalAlert', + options: { + markdowns: [ + '## Dzielenie się jest Fajne!', + '', + 'Podziel się tymi drzewami GIT-a z przyjaciółmi, wpisując `export tree` oraz `import tree`.', + '', + 'Czy masz coś, co warto wiedzieć o GIT-cie? Spróbuj zbudować swój poziom wpisując `build level` lub spróbuj poziomu znajomego wpisując `import level`', + '', + 'Aby zobaczyć wszystkie polecenia, wpisz `show commands`. Pod spodem są "małe skarby" jak `undo`(cofnij) i `reset`', + '', + 'Na razie zacznijmy od wpisania `levels`...' + ] + } + }], + 'ta_IN': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## Git Branching கற்க வரவேற்கிறோம்', + '', + 'கிட் கற்க ஆர்வமா? அப்படியானால் நீங்கள் சரியான இடத்திற்கு வந்துவிட்டீர்கள்! ', + '"Learn Git Branching" Git ஐக் கற்றுக்கொள்வதற்கான வரைபடம் மற்றும் செயல்முறை ', + 'பயிற்சியுடன் கூடிய சிரந்த கருவி; ', + 'உங்களை சோதிக்கும் வகையிலான நிலைகளுடன் மிகுந்த சக்திவாய்ந்த அம்சங்களை ', + 'படிப்படியாகவும், சில சமையம் விளையாட்டாகவும் கற்றுத்தர கூடியது.', + '', + 'இந்த அறிவிற்ப்புக்கு பிறகு, நாங்கள் வழங்க உள்ள பல்வேறு நிலைகளை நீங்கள் காண்பீர்கள். ', + 'நீங்கள் ஆரம்ம நிலையில் இருந்தால், முதல் கட்டத்தில் இருந்து தொடங்கவும். ', + 'கிட்டின் சில அடிப்படைகளை நீங்கள் ஏற்கனவே அறிந்திருந்தால், மெலும் உள்ள கடினமான கட்டங்களை முயற்ச்சி செய்யுங்கள்.', + '', + 'தேவையானால் `show commands` ஐ பயன்படுத்தி அனைத்து கட்டளைகளையும் முனையத்தில் பார்க்கலாம்.', + '', + 'பின்குறிப்பு: அடுத்தமுறை நேராக sandbox செல்ல வேண்டுமா?', + 'அப்படியானால் பின் வரும் இணைப்பை பயன்பாடித்துக ', + '[this special link](https://pcottle.github.io/learnGitBranching/?NODEMO)', + '', + 'பின்குறிப்பு: GitHub (பெரிய அளவில் பயன்பாட்டில் உள்ள இணையதலம்) `main` என்ற கிழையை `master`-க்கு பதில் ', + 'முன்னிருப்பு கிழையாக பயன் படுத்த உள்ளது [more details available here](https://github.com/github/renaming). ', + 'இந்த மாற்றத்தை பின்னோக்கி இணக்கமான வழியில் பொருத்துவதற்காக, `main`-ஐ முதன்மையாக கருதி ', + 'இந்த இரண்டு பெயர்களும் ஒன்றுக்கொன்று மாற்றுப்பெயர்களாகக் கருதப்படும். ', + 'இந்த மாற்றத்தை அனைத்து நிலை உள்ளடக்கங்களிலும் புதுப்பிக்க நாங்கள் சிறந்த முயற்சியை ', + 'மேற்கொண்டோம், ஆயினும் ஏதேனும் விடுபட்டி இருந்தால் PR உருவாக்கி உதவுங்கள்.', + 'ஒருபக்கச்சார்பான சொற்களிலிருந்து விலகிச் செல்ல உதவியதற்கு நன்றி.' + ] + } + }], }; diff --git a/src/js/git/commands.js b/src/js/git/commands.js index 76a9165e..2b385d9d 100644 --- a/src/js/git/commands.js +++ b/src/js/git/commands.js @@ -1,4 +1,4 @@ -var _ = require('underscore'); +var escapeString = require('../util/escapeString'); var intl = require('../intl'); var Graph = require('../graph'); @@ -19,7 +19,7 @@ function isColonRefspec(str) { } var assertIsRef = function(engine, ref) { - engine.resolveID(ref); // will throw giterror if cant resolve + engine.resolveID(ref); // will throw git error if can't resolve }; var validateBranchName = function(engine, name) { @@ -83,7 +83,7 @@ var assertOriginSpecified = function(generalArgs) { if (generalArgs[0] !== 'origin') { throw new GitError({ msg: intl.todo( - generalArgs[0] + ' is not a remote in your repository! try adding origin that argument' + generalArgs[0] + ' is not a remote in your repository! try adding origin to that argument' ) }); } @@ -107,7 +107,7 @@ var assertBranchIsRemoteTracking = function(engine, branchName) { if (!tracking) { throw new GitError({ msg: intl.todo( - branchName + ' is not a remote tracking branch! I dont know where to push' + branchName + ' is not a remote tracking branch! I don\'t know where to push' ) }); } @@ -190,7 +190,7 @@ var commandConfig = { var set = Graph.getUpstreamSet(engine, 'HEAD'); // first resolve all the refs (as an error check) - var toCherrypick = _.map(generalArgs, function(arg) { + var toCherrypick = generalArgs.map(function (arg) { var commit = engine.getCommitFromRef(arg); // and check that its not upstream if (set[commit.get('id')]) { @@ -253,9 +253,9 @@ var commandConfig = { source = firstArg; assertIsBranch(engine.origin, source); // get o/master locally if master is specified - destination = engine.origin.refs[source].getPrefixedID(); + destination = engine.origin.resolveID(source).getPrefixedID(); } else { - // cant be detached + // can't be detached if (engine.getDetachedHead()) { throw new GitError({ msg: intl.todo('Git pull can not be executed in detached HEAD mode if no remote branch specified!') @@ -394,7 +394,7 @@ var commandConfig = { source = firstArg; assertIsBranch(engine.origin, source); // get o/master locally if master is specified - destination = engine.origin.refs[source].getPrefixedID(); + destination = engine.origin.resolveID(source).getPrefixedID(); } if (source) { // empty string fails this check assertIsRef(engine.origin, source); @@ -431,7 +431,7 @@ var commandConfig = { names = names.concat(generalArgs); command.validateArgBounds(names, 1, Number.MAX_VALUE, '-d'); - _.each(names, function(name) { + names.forEach(function(name) { engine.validateAndDeleteBranch(name); }); return; @@ -447,8 +447,8 @@ var commandConfig = { assertIsRemoteBranch(engine, remoteBranch); assertIsBranch(engine, branch); engine.setLocalToTrackRemote( - engine.refs[branch], - engine.refs[remoteBranch] + engine.resolveID(branch), + engine.resolveID(remoteBranch) ); return; } @@ -519,7 +519,7 @@ var commandConfig = { command.addWarning( intl.str('git-warning-hard') ); - // dont absorb the arg off of --hard + // don't absorb the arg off of --hard generalArgs = generalArgs.concat(commandOptions['--hard']); } @@ -574,25 +574,26 @@ var commandConfig = { } }, + revlist: { + dontCountForGolf: true, + displayName: 'rev-list', + regex: /^git +rev-list($|\s)/, + execute: function(engine, command) { + var generalArgs = command.getGeneralArgs(); + command.validateArgBounds(generalArgs, 1); + + engine.revlist(generalArgs); + } + }, + log: { dontCountForGolf: true, regex: /^git +log($|\s)/, execute: function(engine, command) { var generalArgs = command.getGeneralArgs(); - if (generalArgs.length == 2) { - // do fancy git log branchA ^branchB - if (generalArgs[1][0] == '^') { - engine.logWithout(generalArgs[0], generalArgs[1]); - } else { - throw new GitError({ - msg: intl.str('git-error-options') - }); - } - } - - command.oneArgImpliedHead(generalArgs); - engine.log(generalArgs[0]); + command.impliedHead(generalArgs, 0); + engine.log(generalArgs); } }, @@ -742,7 +743,7 @@ var commandConfig = { var refspecParts = firstArg.split(':'); source = refspecParts[0]; destination = validateBranchName(engine, refspecParts[1]); - if (source === "" && !engine.origin.refs[destination]) { + if (source === "" && !engine.origin.resolveID(destination)) { throw new GitError({ msg: intl.todo( 'cannot delete branch ' + options.destination + ' which doesnt exist' @@ -769,7 +770,7 @@ var commandConfig = { sourceObj.getRemoteTrackingBranchID()) { assertBranchIsRemoteTracking(engine, source); var remoteBranch = sourceObj.getRemoteTrackingBranchID(); - destination = engine.refs[remoteBranch].getBaseID(); + destination = engine.resolveID(remoteBranch).getBaseID(); } else { destination = validateBranchName(engine, source); } @@ -810,8 +811,41 @@ var commandConfig = { tag: { regex: /^git +tag($|\s)/, + options: [ + '-d' + ], execute: function(engine, command) { var generalArgs = command.getGeneralArgs(); + var commandOptions = command.getOptionsMap(); + + if (commandOptions['-d']) { + var tagID = commandOptions['-d']; + var tagToRemove; + + assertIsRef(engine, tagID); + + command.oneArgImpliedHead(tagID); + engine.tagCollection.each(function(tag) { + if(tag.get('id') == tagID){ + tagToRemove = tag; + } + }, true); + + if(tagToRemove == undefined){ + throw new GitError({ + msg: intl.todo( + 'No tag found, nothing to remove' + ) + }); + } + + engine.tagCollection.remove(tagToRemove); + delete engine.refs[tagID]; + + engine.gitVisuals.refreshTree(); + return; + } + if (generalArgs.length === 0) { var tags = engine.getTags(); engine.printTags(tags); @@ -821,6 +855,48 @@ var commandConfig = { command.twoArgsImpliedHead(generalArgs); engine.tag(generalArgs[0], generalArgs[1]); } + }, + + switch: { + sc: /^(gsw|git sw)($|\s)/, + regex: /^git +switch($|\s)/, + options: [ + '-c', + '-' + ], + execute: function(engine, command) { + var generalArgs = command.getGeneralArgs(); + var commandOptions = command.getOptionsMap(); + + var args = null; + if (commandOptions['-c']) { + // the user is really trying to just make a + // branch and then switch to it. so first: + args = commandOptions['-c'].concat(generalArgs); + command.twoArgsImpliedHead(args, '-c'); + + var validId = engine.validateBranchName(args[0]); + engine.branch(validId, args[1]); + engine.checkout(validId); + return; + } + + if (commandOptions['-']) { + // get the heads last location + var lastPlace = engine.HEAD.get('lastLastTarget'); + if (!lastPlace) { + throw new GitError({ + msg: intl.str('git-result-nothing') + }); + } + engine.HEAD.set('target', lastPlace); + return; + } + + command.validateArgBounds(generalArgs, 1, 1); + + engine.checkout(engine.crappyUnescape(generalArgs[0])); + } } }; @@ -830,7 +906,7 @@ var instantCommands = [ intl.str('git-version'), '
', intl.str('git-usage'), - _.escape(intl.str('git-usage-command')), + escapeString(intl.str('git-usage-command')), '
', intl.str('git-supported-commands'), '
' @@ -838,9 +914,10 @@ var instantCommands = [ var commands = require('../commands').commands.getOptionMap()['git']; // build up a nice display of what we support - _.each(commands, function(commandOptions, command) { + Object.keys(commands).forEach(function(command) { + var commandOptions = commands[command]; lines.push('git ' + command); - _.each(commandOptions, function(vals, optionName) { + Object.keys(commandOptions).forEach(function(optionName) { lines.push('\t ' + optionName); }, this); }, this); @@ -856,4 +933,3 @@ var instantCommands = [ exports.commandConfig = commandConfig; exports.instantCommands = instantCommands; - diff --git a/src/js/git/headless.js b/src/js/git/headless.js index ffc7187a..81472285 100644 --- a/src/js/git/headless.js +++ b/src/js/git/headless.js @@ -36,7 +36,7 @@ function getMockFactory() { }; mockFactory.highlightEachWithPromise = function(chain, toRebase, destBranch) { - // dont add any steps + // don't add any steps return chain; }; @@ -109,6 +109,8 @@ HeadlessGit.prototype.sendCommand = function(value, entireCommandPromise) { var chain = deferred.promise; var startTime = new Date().getTime(); + var commands = []; + util.splitTextCommand(value, function(commandStr) { chain = chain.then(function() { var commandObj = new Command({ @@ -117,6 +119,7 @@ HeadlessGit.prototype.sendCommand = function(value, entireCommandPromise) { var thisDeferred = Q.defer(); this.gitEngine.dispatch(commandObj, thisDeferred); + commands.push(commandObj); return thisDeferred.promise; }.bind(this)); }, this); @@ -124,7 +127,7 @@ HeadlessGit.prototype.sendCommand = function(value, entireCommandPromise) { chain.then(function() { var nowTime = new Date().getTime(); if (entireCommandPromise) { - entireCommandPromise.resolve(); + entireCommandPromise.resolve(commands); } }); @@ -135,8 +138,8 @@ HeadlessGit.prototype.sendCommand = function(value, entireCommandPromise) { console.log('!!!!!!!!!!!!!!!!!!!!!!'); }); deferred.resolve(); + return chain; }; exports.HeadlessGit = HeadlessGit; exports.getTreeQuick = getTreeQuick; - diff --git a/src/js/git/index.js b/src/js/git/index.js index f0188246..bd5791c9 100644 --- a/src/js/git/index.js +++ b/src/js/git/index.js @@ -1,4 +1,3 @@ -var _ = require('underscore'); var Backbone = require('backbone'); var Q = require('q'); @@ -41,7 +40,7 @@ function GitEngine(options) { this.eventBaton = options.eventBaton; this.eventBaton.stealBaton('processGitCommand', this.dispatch, this); - // poor man's dependency injection. we cant reassign + // poor man's dependency injection. we can't reassign // the module variable because its get clobbered :P this.animationFactory = (options.animationFactory) ? options.animationFactory : AnimationFactory; @@ -61,7 +60,7 @@ GitEngine.prototype.initUniqueID = function() { GitEngine.prototype.handleModeChange = function(vcs, callback) { if (this.mode === vcs) { - // dont fire event aggressively + // don't fire event aggressively callback(); return; } @@ -96,8 +95,8 @@ GitEngine.prototype.setMode = function(vcs) { deferred.resolve(); var chain = deferred.promise; - // this stuff is tricky because we dont animate when - // we didnt do anything, but we DO animate when + // this stuff is tricky because we don't animate when + // we didn't do anything, but we DO animate when // either of the operations happen. so a lot of // branching ahead... var neededUpdate = this.updateAllBranchesForHg(); @@ -170,7 +169,7 @@ GitEngine.prototype.exportTreeForBranch = function(branchName) { // now loop through and delete commits var commitsToLoop = tree.commits; tree.commits = {}; - _.each(commitsToLoop, function(commit, id) { + commitsToLoop.forEach(function(commit, id) { if (set[id]) { // if included in target branch tree.commits[id] = commit; @@ -179,7 +178,7 @@ GitEngine.prototype.exportTreeForBranch = function(branchName) { var branchesToLoop = tree.branches; tree.branches = {}; - _.each(branchesToLoop, function(branch, id) { + branchesToLoop.forEach(function(branch, id) { if (id === branchName) { tree.branches[id] = branch; } @@ -200,30 +199,28 @@ GitEngine.prototype.exportTree = function() { HEAD: null }; - _.each(this.branchCollection.toJSON(), function(branch) { + this.branchCollection.toJSON().forEach(function(branch) { branch.target = branch.target.get('id'); delete branch.visBranch; totalExport.branches[branch.id] = branch; }); - _.each(this.commitCollection.toJSON(), function(commit) { + this.commitCollection.toJSON().forEach(function(commit) { // clear out the fields that reference objects and create circular structure - _.each(Commit.prototype.constants.circularFields, function(field) { + Commit.prototype.constants.circularFields.forEach(function(field) { delete commit[field]; - }, this); + }); // convert parents - var parents = []; - _.each(commit.parents, function(par) { - parents.push(par.get('id')); + commit.parents = (commit.parents || []).map(function(par) { + return par.get('id'); }); - commit.parents = parents; totalExport.commits[commit.id] = commit; }, this); - _.each(this.tagCollection.toJSON(), function(tag) { + this.tagCollection.toJSON().forEach(function(tag) { delete tag.visTag; tag.target = tag.target.get('id'); @@ -282,18 +279,18 @@ GitEngine.prototype.instantiateFromTree = function(tree) { // now we do the loading part var createdSoFar = {}; - _.each(tree.commits, function(commitJSON) { + Object.values(tree.commits).forEach(function(commitJSON) { var commit = this.getOrMakeRecursive(tree, createdSoFar, commitJSON.id, this.gitVisuals); this.commitCollection.add(commit); }, this); - _.each(tree.branches, function(branchJSON) { + Object.values(tree.branches).forEach(function(branchJSON) { var branch = this.getOrMakeRecursive(tree, createdSoFar, branchJSON.id, this.gitVisuals); this.branchCollection.add(branch, {silent: true}); }, this); - _.each(tree.tags, function(tagJSON) { + Object.values(tree.tags || {}).forEach(function(tagJSON) { var tag = this.getOrMakeRecursive(tree, createdSoFar, tagJSON.id, this.gitVisuals); this.tagCollection.add(tag, {silent: true}); @@ -318,7 +315,7 @@ GitEngine.prototype.instantiateFromTree = function(tree) { if (tree.originTree) { var treeString = JSON.stringify(tree.originTree); - // if we dont have an animation queue (like when loading + // if we don't have an animation queue (like when loading // right away), just go ahead and make an empty one this.animationQueue = this.animationQueue || new AnimationQueue({ callback: function() {} @@ -362,7 +359,8 @@ GitEngine.prototype.makeOrigin = function(treeString) { var originTree = JSON.parse(unescape(treeString)); // make an origin branch for each branch mentioned in the tree if its // not made already... - _.each(originTree.branches, function(branchJSON, branchName) { + Object.keys(originTree.branches).forEach(function(branchName) { + var branchJSON = originTree.branches[branchName]; if (this.refs[ORIGIN_PREFIX + branchName]) { // we already have this branch return; @@ -383,7 +381,7 @@ GitEngine.prototype.makeOrigin = function(treeString) { }; GitEngine.prototype.makeRemoteBranchIfNeeded = function(branchName) { - if (this.refs[ORIGIN_PREFIX + branchName]) { + if (this.doesRefExist(ORIGIN_PREFIX + branchName)) { return; } // if its not a branch on origin then bounce @@ -396,7 +394,7 @@ GitEngine.prototype.makeRemoteBranchIfNeeded = function(branchName) { }; GitEngine.prototype.makeBranchIfNeeded = function(branchName) { - if (this.refs[branchName]) { + if (this.doesRefExist(branchName)) { return; } var where = this.findCommonAncestorForRemote( @@ -407,7 +405,7 @@ GitEngine.prototype.makeBranchIfNeeded = function(branchName) { }; GitEngine.prototype.makeRemoteBranchForRemote = function(branchName) { - var target = this.origin.refs[branchName].get('target'); + var target = this.origin.resolveID(branchName).get('target'); var originTarget = this.findCommonAncestorWithRemote( target.get('id') ); @@ -434,7 +432,7 @@ GitEngine.prototype.findCommonAncestorForRemote = function(myTarget) { return this.getCommonAncestor( leftTarget, rightTarget, - true // dont throw since we dont know the order here. + true // don't throw since we don't know the order here. ).get('id'); }; @@ -451,7 +449,7 @@ GitEngine.prototype.findCommonAncestorWithRemote = function(originTarget) { // Like above, could have two parents var leftTarget = this.findCommonAncestorWithRemote(parents[0].get('id')); var rightTarget = this.findCommonAncestorWithRemote(parents[1].get('id')); - return this.getCommonAncestor(leftTarget, rightTarget, true /* dont throw */).get('id'); + return this.getCommonAncestor(leftTarget, rightTarget, true /* don't throw */).get('id'); }; GitEngine.prototype.makeBranchOnOriginAndTrack = function(branchName, target) { @@ -482,9 +480,9 @@ GitEngine.prototype.setLocalToTrackRemote = function(localBranch, remoteBranch) } var msg = 'local branch "' + - localBranch.get('id') + + this.postProcessBranchID(localBranch.get('id')) + '" set to track remote branch "' + - remoteBranch.get('id') + + this.postProcessBranchID(remoteBranch.get('id')) + '"'; this.command.addWarning(intl.todo(msg)); }; @@ -518,7 +516,7 @@ GitEngine.prototype.getOrMakeRecursive = function( if (type == 'HEAD') { var headJSON = tree.HEAD; - var HEAD = new Ref(_.extend( + var HEAD = new Ref(Object.assign( tree.HEAD, { target: this.getOrMakeRecursive(tree, createdSoFar, headJSON.target) @@ -531,7 +529,7 @@ GitEngine.prototype.getOrMakeRecursive = function( if (type == 'branch') { var branchJSON = tree.branches[objID]; - var branch = new Branch(_.extend( + var branch = new Branch(Object.assign( tree.branches[objID], { target: this.getOrMakeRecursive(tree, createdSoFar, branchJSON.target) @@ -544,7 +542,7 @@ GitEngine.prototype.getOrMakeRecursive = function( if (type == 'tag') { var tagJSON = tree.tags[objID]; - var tag = new Tag(_.extend( + var tag = new Tag(Object.assign( tree.tags[objID], { target: this.getOrMakeRecursive(tree, createdSoFar, tagJSON.target) @@ -558,12 +556,11 @@ GitEngine.prototype.getOrMakeRecursive = function( // for commits, we need to grab all the parents var commitJSON = tree.commits[objID]; - var parentObjs = []; - _.each(commitJSON.parents, function(parentID) { - parentObjs.push(this.getOrMakeRecursive(tree, createdSoFar, parentID)); + var parentObjs = commitJSON.parents.map(function(parentID) { + return this.getOrMakeRecursive(tree, createdSoFar, parentID); }, this); - var commit = new Commit(_.extend( + var commit = new Commit(Object.assign( commitJSON, { parents: parentObjs, @@ -671,7 +668,7 @@ GitEngine.prototype.validateBranchName = function(name) { GitEngine.prototype.validateAndMakeBranch = function(id, target) { id = this.validateBranchName(id); - if (this.refs[id]) { + if (this.doesRefExist(id)) { throw new GitError({ msg: intl.str( 'bad-branch-name', @@ -689,7 +686,7 @@ GitEngine.prototype.validateAndMakeTag = function(id, target) { throw new GitError({ msg: intl.str( 'bad-tag-name', - { tag: name } + { tag: id } ) }); } @@ -697,9 +694,22 @@ GitEngine.prototype.validateAndMakeTag = function(id, target) { this.makeTag(id, target); }; +GitEngine.prototype.postProcessBranchID = function(id) { + if (id.match(/\bmaster\b/)) { + id = id.replace(/\bmaster\b/, 'main'); + } + return id; +} + GitEngine.prototype.makeBranch = function(id, target) { + // all main branches are stored as master under the hood + if (id.match(/\bmain\b/)) { + id = id.replace(/\bmain\b/, 'master'); + } + if (this.refs[id]) { - throw new Error('woah already have that'); + var err = new Error(); + throw new Error('woah already have that ref ' + id + ' ' + err.stack); } var branch = new Branch({ @@ -726,7 +736,7 @@ GitEngine.prototype.makeTag = function(id, target) { }; GitEngine.prototype.getHead = function() { - return _.clone(this.HEAD); + return Object.assign({}, this.HEAD); }; GitEngine.prototype.getTags = function() { @@ -758,14 +768,14 @@ GitEngine.prototype.getBranches = function() { GitEngine.prototype.getRemoteBranches = function() { var all = this.getBranches(); - return _.filter(all, function(branchJSON) { + return all.filter(function(branchJSON) { return branchJSON.remote === true; }); }; GitEngine.prototype.getLocalBranches = function() { var all = this.getBranches(); - return _.filter(all, function(branchJSON) { + return all.filter(function(branchJSON) { return branchJSON.remote === false; }); }; @@ -774,17 +784,16 @@ GitEngine.prototype.printBranchesWithout = function(without) { var commitToBranches = this.getUpstreamBranchSet(); var commitID = this.getCommitFromRef(without).get('id'); - var toPrint = []; - _.each(commitToBranches[commitID], function(branchJSON) { + var toPrint = commitToBranches[commitID].map(function (branchJSON) { branchJSON.selected = this.HEAD.get('target').get('id') == branchJSON.id; - toPrint.push(branchJSON); + return branchJSON; }, this); this.printBranches(toPrint); }; GitEngine.prototype.printBranches = function(branches) { var result = ''; - _.each(branches, function(branch) { + branches.forEach(function (branch) { result += (branch.selected ? '* ' : '') + branch.id + '\n'; }); throw new CommandResult({ @@ -794,7 +803,7 @@ GitEngine.prototype.printBranches = function(branches) { GitEngine.prototype.printTags = function(tags) { var result = ''; - _.each(tags, function(tag) { + tags.forEach(function (tag) { result += tag.id + '\n'; }); throw new CommandResult({ @@ -846,7 +855,7 @@ GitEngine.prototype.makeCommit = function(parents, id, options) { id = this.getUniqueID(); } - var commit = new Commit(_.extend({ + var commit = new Commit(Object.assign({ parents: parents, id: id, gitVisuals: this.gitVisuals @@ -861,7 +870,7 @@ GitEngine.prototype.makeCommit = function(parents, id, options) { GitEngine.prototype.revert = function(whichCommits) { // resolve the commits we will rebase - var toRevert = _.map(whichCommits, function(stringRef) { + var toRevert = whichCommits.map(function(stringRef) { return this.getCommitFromRef(stringRef); }, this); @@ -895,11 +904,11 @@ GitEngine.prototype.revert = function(whichCommits) { }.bind(this); // set up the promise chain - _.each(toRevert, function(commit) { + toRevert.forEach(function (commit) { chain = chain.then(function() { return chainStep(commit); }); - }, this); + }); // done! update our location chain = chain.then(function() { @@ -934,7 +943,7 @@ GitEngine.prototype.setupCherrypickChain = function(toCherrypick) { ); }.bind(this); - _.each(toCherrypick, function(arg) { + toCherrypick.forEach(function (arg) { chain = chain.then(function() { return chainStep(arg); }); @@ -1015,15 +1024,15 @@ GitEngine.prototype.getTargetGraphDifference = function( while (toExplore.length) { var here = toExplore.pop(); difference.push(here); - _.each(here.parents, pushParent); + here.parents.forEach(pushParent); } - // filter because we werent doing graph search + // filter because we weren't doing graph search var differenceUnique = Graph.getUniqueObjects(difference); /** * Ok now we have to determine the order in which to make these commits. * We used to just sort by depth because we were lazy but that is incorrect - * since it doesnt represent the actual dependency tree of the commits. + * since it doesn't represent the actual dependency tree of the commits. * * So here is what we are going to do -- loop through the differenceUnique * set and find a commit that has _all_ its parents in the targetSet. Then @@ -1069,14 +1078,15 @@ GitEngine.prototype.push = function(options) { return; } - var sourceBranch = this.refs[options.source]; + var sourceBranch = this.resolveID(options.source); if (sourceBranch && sourceBranch.attributes.type === 'tag') { throw new GitError({ msg: intl.todo('Tags are not allowed as sources for pushing'), }); } - if (!this.origin.refs[options.destination]) { + if (!this.origin.doesRefExist(options.destination)) { + console.warn('ref', options.destination); this.makeBranchOnOriginAndTrack( options.destination, this.getCommitFromRef(sourceBranch) @@ -1087,7 +1097,7 @@ GitEngine.prototype.push = function(options) { this.animationFactory.playRefreshAnimation(this.origin.gitVisuals); this.animationFactory.playRefreshAnimation(this.gitVisuals); } - var branchOnRemote = this.origin.refs[options.destination]; + var branchOnRemote = this.origin.resolveID(options.destination); var sourceLocation = this.resolveID(options.source || 'HEAD'); // first check if this is even allowed by checking the sync between @@ -1112,8 +1122,8 @@ GitEngine.prototype.push = function(options) { ); if (!commitsToMake.length) { if (!options.force) { - // We are already up to date, and we cant be deleting - // either since we dont have --force + // We are already up to date, and we can't be deleting + // either since we don't have --force throw new GitError({ msg: intl.str('git-error-origin-fetch-uptodate') }); @@ -1133,16 +1143,16 @@ GitEngine.prototype.push = function(options) { // now here is the tricky part -- the difference between local master // and remote master might be commits C2, C3, and C4, but the remote - // might already have those commits. In this case, we dont need to + // might already have those commits. In this case, we don't need to // make them, so filter these out - commitsToMake = _.filter(commitsToMake, function(commitJSON) { + commitsToMake = commitsToMake.filter(function(commitJSON) { return !this.origin.refs[commitJSON.id]; }, this); var makeCommit = function(id, parentIDs) { // need to get the parents first. since we order by depth, we know // the dependencies are there already - var parents = _.map(parentIDs, function(parentID) { + var parents = parentIDs.map(function(parentID) { return this.origin.refs[parentID]; }, this); return this.origin.makeCommit(parents, id); @@ -1160,7 +1170,7 @@ GitEngine.prototype.push = function(options) { var deferred = Q.defer(); var chain = deferred.promise; - _.each(commitsToMake, function(commitJSON) { + commitsToMake.forEach(function(commitJSON) { chain = chain.then(function() { return this.animationFactory.playHighlightPromiseAnimation( this.refs[commitJSON.id], @@ -1188,7 +1198,7 @@ GitEngine.prototype.push = function(options) { // HAX HAX update master and remote tracking for master chain = chain.then(function() { var localCommit = this.getCommitFromRef(sourceLocation); - this.setTargetLocation(this.refs[ORIGIN_PREFIX + options.destination], localCommit); + this.setTargetLocation(this.resolveID(ORIGIN_PREFIX + options.destination), localCommit); return this.animationFactory.playRefreshAnimation(this.gitVisuals); }.bind(this)); @@ -1250,7 +1260,7 @@ GitEngine.prototype.fetch = function(options) { } // get all remote branches and specify the dest / source pairs var allBranchesOnRemote = this.origin.branchCollection.toArray(); - var sourceDestPairs = _.map(allBranchesOnRemote, function(branch) { + var sourceDestPairs = allBranchesOnRemote.map(function(branch) { var branchName = branch.get('id'); didMakeBranch = didMakeBranch || this.makeRemoteBranchIfNeeded(branchName); @@ -1267,7 +1277,7 @@ GitEngine.prototype.fetchCore = function(sourceDestPairs, options) { // first check if our local remote branch is upstream of the origin branch set. // this check essentially pretends the local remote branch is in origin and // could be fast forwarded (basic sanity check) - _.each(sourceDestPairs, function(pair) { + sourceDestPairs.forEach(function (pair) { this.checkUpstreamOfSource( this, this.origin, @@ -1278,13 +1288,13 @@ GitEngine.prototype.fetchCore = function(sourceDestPairs, options) { // then we get the difference in commits between these two graphs var commitsToMake = []; - _.each(sourceDestPairs, function(pair) { + sourceDestPairs.forEach(function (pair) { commitsToMake = commitsToMake.concat(this.getTargetGraphDifference( this, this.origin, pair.destination, pair.source, - _.extend( + Object.assign( {}, options, {dontThrowOnNoFetch: true} @@ -1307,17 +1317,17 @@ GitEngine.prototype.fetchCore = function(sourceDestPairs, options) { // now here is the tricky part -- the difference between local master // and remote master might be commits C2, C3, and C4, but we - // might already have those commits. In this case, we dont need to + // might already have those commits. In this case, we don't need to // make them, so filter these out - commitsToMake = _.filter(commitsToMake, function(commitJSON) { + commitsToMake = commitsToMake.filter(function(commitJSON) { return !this.refs[commitJSON.id]; }, this); var makeCommit = function(id, parentIDs) { // need to get the parents first. since we order by depth, we know // the dependencies are there already - var parents = _.map(parentIDs, function(parentID) { - return this.refs[parentID]; + var parents = parentIDs.map(function(parentID) { + return this.resolveID(parentID); }, this); return this.makeCommit(parents, id); }.bind(this); @@ -1341,7 +1351,7 @@ GitEngine.prototype.fetchCore = function(sourceDestPairs, options) { } var originBranchSet = this.origin.getUpstreamBranchSet(); - _.each(commitsToMake, function(commitJSON) { + commitsToMake.forEach(function (commitJSON) { // technically we could grab the wrong one here // but this works for now var originBranch = originBranchSet[commitJSON.id][0].obj; @@ -1349,7 +1359,7 @@ GitEngine.prototype.fetchCore = function(sourceDestPairs, options) { chain = chain.then(function() { return this.animationFactory.playHighlightPromiseAnimation( - this.origin.refs[commitJSON.id], + this.origin.resolveID(commitJSON.id), localBranch ); }.bind(this)); @@ -1364,8 +1374,8 @@ GitEngine.prototype.fetchCore = function(sourceDestPairs, options) { chain = chain.then(function() { // update all the destinations - _.each(sourceDestPairs, function(pair) { - var ours = this.refs[pair.destination]; + sourceDestPairs.forEach(function (pair) { + var ours = this.resolveID(pair.destination); var theirCommitID = this.origin.getCommitFromRef(pair.source).get('id'); // by definition we just made the commit with this id, // so we can grab it now @@ -1404,7 +1414,7 @@ GitEngine.prototype.pull = function(options) { return; } - var destBranch = this.refs[options.destination]; + var destBranch = this.resolveID(options.destination); // then either rebase or merge if (options.isRebase) { this.pullFinishWithRebase(pendingFetch, localBranch, destBranch); @@ -1555,11 +1565,9 @@ GitEngine.prototype.fakeTeamwork = function(numToMake, branch) { var deferred = Q.defer(); var chain = deferred.promise; - _.each(_.range(numToMake), function(i) { - chain = chain.then(function() { - return chainStep(); - }); - }); + for(var i = 0; i < numToMake; i++) { + chain = chain.then(chainStep); + } this.animationQueue.thenFinish(chain, deferred); }; @@ -1617,7 +1625,8 @@ GitEngine.prototype.resolveName = function(someRef) { GitEngine.prototype.resolveID = function(idOrTarget) { if (idOrTarget === null || idOrTarget === undefined) { - throw new Error('Dont call this with null / undefined'); + var err = new Error(); + throw new Error('Don\'t call this with null / undefined: ' + err.stack); } if (typeof idOrTarget !== 'string') { @@ -1658,8 +1667,20 @@ GitEngine.prototype.resolveRelativeRef = function(commit, relative) { return commit; }; +GitEngine.prototype.doesRefExist = function(ref) { + if (ref.match(/\bmain\b/)) { + ref = ref.replace(/\bmain\b/, 'master'); + } + return !!this.refs[ref] +}; + GitEngine.prototype.resolveStringRef = function(ref) { ref = this.crappyUnescape(ref); + + if (ref.match(/\bmain\b/)) { + ref = ref.replace(/\bmain\b/, 'master'); + } + if (this.refs[ref]) { return this.refs[ref]; } @@ -1671,7 +1692,7 @@ GitEngine.prototype.resolveStringRef = function(ref) { // Attempt to split ref string into a reference and a string of ~ and ^ modifiers. var startRef = null; var relative = null; - var regex = /^([a-zA-Z0-9]+)(([~\^]\d*)*)/; + var regex = /^([a-zA-Z0-9]+)(([~\^]\d*)*)$/; var matches = regex.exec(ref); if (matches) { startRef = matches[1]; @@ -1736,13 +1757,13 @@ GitEngine.prototype.updateBranchesFromSet = function(commitSet) { var branchesToUpdate = {}; // now loop over the set we got passed in and find which branches // that means (aka intersection) - _.each(commitSet, function(val, id) { - _.each(upstreamSet[id], function(branchJSON) { + commitSet.forEach(function (val, id) { + upstreamSet[id].forEach(function (branchJSON) { branchesToUpdate[branchJSON.id] = true; }); }, this); - var branchList = _.map(branchesToUpdate, function(val, id) { + var branchList = branchesToUpdate.map(function(val, id) { return id; }); return this.updateBranchesForHg(branchList); @@ -1767,7 +1788,7 @@ GitEngine.prototype.syncRemoteBranchFills = function() { } var originBranch = this.origin.refs[branch.getBaseID()]; if (!originBranch.get('visBranch')) { - // testing mode doesnt get this + // testing mode doesn't get this return; } var originFill = originBranch.get('visBranch').get('fill'); @@ -1777,7 +1798,7 @@ GitEngine.prototype.syncRemoteBranchFills = function() { GitEngine.prototype.updateBranchesForHg = function(branchList) { var hasUpdated = false; - _.each(branchList, function(branchID) { + branchList.forEach(function (branchID) { // ok now just check if this branch has a more recent commit available. // that mapping is easy because we always do rebase alt id -- // theres no way to have C3' and C3''' but no C3''. so just @@ -1808,7 +1829,7 @@ GitEngine.prototype.updateBranchesForHg = function(branchList) { GitEngine.prototype.updateCommitParentsForHgRebase = function(commitSet) { var anyChange = false; - _.each(commitSet, function(val, commitID) { + Object.keys(commitSet).forEach(function(commitID) { var commit = this.refs[commitID]; var thisUpdated = commit.checkForUpdatedParent(this); anyChange = anyChange || thisUpdated; @@ -1823,9 +1844,9 @@ GitEngine.prototype.pruneTreeAndPlay = function() { GitEngine.prototype.pruneTree = function() { var set = this.getUpstreamBranchSet(); - // dont prune commits that HEAD depends on + // don't prune commits that HEAD depends on var headSet = Graph.getUpstreamSet(this, 'HEAD'); - _.each(headSet, function(val, commitID) { + Object.keys(headSet).forEach(function(commitID) { set[commitID] = true; }); @@ -1846,7 +1867,7 @@ GitEngine.prototype.pruneTree = function() { this.command.addWarning(intl.str('hg-prune-tree')); } - _.each(toDelete, function(commit) { + toDelete.forEach(function (commit) { commit.removeFromParents(); this.commitCollection.remove(commit); @@ -1877,7 +1898,7 @@ GitEngine.prototype.getUpstreamCollectionSet = function(collection) { var inArray = function(arr, id) { var found = false; - _.each(arr, function(wrapper) { + arr.forEach(function (wrapper) { if (wrapper.id == id) { found = true; } @@ -1902,7 +1923,7 @@ GitEngine.prototype.getUpstreamCollectionSet = function(collection) { collection.each(function(ref) { var set = bfsSearch(ref.get('target')); - _.each(set, function(id) { + set.forEach(function (id) { commitToSet[id] = commitToSet[id] || []; // only add it if it's not there, so hue blending is ok @@ -2032,21 +2053,19 @@ GitEngine.prototype.idSortFunc = function(cA, cB) { throw new Error('Could not parse commit ID ' + id); }; + // We usually want to sort by reverse chronological order, aka the + // "latest" commits have the highest values. When we did this + // with date sorting, that means the commit C1 at t=0 should have + // a lower value than the commit C2 at t=1. We do this by doing + // t0 - t1 and get a negative number. Same goes for ID sorting, + // which means C1 - C2 = -1 return getNumToSort(cA.get('id')) - getNumToSort(cB.get('id')); }; GitEngine.prototype.dateSortFunc = function(cA, cB) { - var dateA = new Date(cA.get('createTime')); - var dateB = new Date(cB.get('createTime')); - if (dateA - dateB === 0) { - // hmmmmm this still needs fixing. we need to know basically just WHEN a commit was created, but since - // we strip off the date creation field, when loading a tree from string this fails :-/ - // there's actually no way to determine it... - //c.warn('WUT it is equal'); - //c.log(cA, cB); - return GitEngine.prototype.idSortFunc(cA, cB); - } - return dateA - dateB; + // We used to use date sorting, but its hacky so lets switch to ID sorting + // to eliminate non-determinism + return GitEngine.prototype.idSortFunc(cA, cB); }; GitEngine.prototype.hgRebase = function(destination, base) { @@ -2072,14 +2091,14 @@ GitEngine.prototype.hgRebase = function(destination, base) { // and NOWWWwwww get all the descendants of this set var moreSets = []; - _.each(upstream, function(val, id) { + Object.keys(upstream).forEach(function(id) { moreSets.push(this.getDownstreamSet(id)); }, this); var masterSet = {}; masterSet[baseCommit.get('id')] = true; - _.each([upstream, downstream].concat(moreSets), function(set) { - _.each(set, function(val, id) { + [upstream, downstream].concat(moreSets).forEach(function(set) { + Object.keys(set).forEach(function(id) { masterSet[id] = true; }); }); @@ -2087,19 +2106,17 @@ GitEngine.prototype.hgRebase = function(destination, base) { // we also need the branches POINTING to master set var branchMap = {}; var upstreamSet = this.getUpstreamBranchSet(); - _.each(masterSet, function(val, commitID) { + Object.keys(masterSet).forEach(function(commitID) { // now loop over that commits branches - _.each(upstreamSet[commitID], function(branchJSON) { + upstreamSet[commitID].forEach(function(branchJSON) { branchMap[branchJSON.id] = true; }); }); - var branchList = _.map(branchMap, function(val, id) { - return id; - }); + var branchList = Object.keys(branchMap); chain = chain.then(function() { - // now we just moved a bunch of commits, but we havent updated the + // now we just moved a bunch of commits, but we haven't updated the // dangling guys. lets do that and then prune var anyChange = this.updateCommitParentsForHgRebase(masterSet); if (!anyChange) { @@ -2156,7 +2173,7 @@ GitEngine.prototype.rebase = function(targetSource, currentLocation, options) { GitEngine.prototype.getUpstreamDiffSetFromSet = function(stopSet, location) { var set = {}; - _.each(this.getUpstreamDiffFromSet(stopSet, location), function(commit) { + this.getUpstreamDiffFromSet(stopSet, location).forEach(function (commit) { set[commit.get('id')] = true; }); return set; @@ -2189,7 +2206,7 @@ GitEngine.prototype.getInteractiveRebaseCommits = function(targetSource, current // throw out merge's real fast and see if we have anything to do var toRebase = []; - _.each(toRebaseRough, function(commit) { + toRebaseRough.forEach(function (commit) { if (commit.get('parents').length == 1) { toRebase.push(commit); } @@ -2211,7 +2228,7 @@ GitEngine.prototype.rebaseInteractiveTest = function(targetSource, currentLocati var toRebase = this.getInteractiveRebaseCommits(targetSource, currentLocation); var rebaseMap = {}; - _.each(toRebase, function(commit) { + toRebase.forEach(function (commit) { var id = commit.get('id'); rebaseMap[id] = commit; }); @@ -2228,7 +2245,7 @@ GitEngine.prototype.rebaseInteractiveTest = function(targetSource, currentLocati // Verify each chosen commit exists in the list of commits given to the user var extraCommits = []; rebaseOrder = []; - _.each(idsToRebase, function(id) { + idsToRebase.forEach(function (id) { if (id in rebaseMap) { rebaseOrder.push(rebaseMap[id]); } else { @@ -2238,7 +2255,7 @@ GitEngine.prototype.rebaseInteractiveTest = function(targetSource, currentLocati if (extraCommits.length > 0) { throw new GitError({ - msg: intl.todo('Hey those commits dont exist in the set!') + msg: intl.todo('Hey those commits don\'t exist in the set!') }); } } @@ -2281,16 +2298,16 @@ GitEngine.prototype.rebaseInteractive = function(targetSource, currentLocation, var initialCommitOrdering; if (options.initialCommitOrdering && options.initialCommitOrdering.length > 0) { var rebaseMap = {}; - _.each(toRebase, function(commit) { + toRebase.forEach(function (commit) { rebaseMap[commit.get('id')] = true; }); // Verify each chosen commit exists in the list of commits given to the user initialCommitOrdering = []; - _.each(options.initialCommitOrdering[0].split(','), function(id) { + options.initialCommitOrdering[0].split(',').forEach(function (id) { if (!rebaseMap[id]) { throw new GitError({ - msg: intl.todo('Hey those commits dont exist in the set!') + msg: intl.todo('Hey those commits don\'t exist in the set!') }); } initialCommitOrdering.push(id); @@ -2313,20 +2330,20 @@ GitEngine.prototype.filterRebaseCommits = function( options ) { var changesAlreadyMade = {}; - _.each(stopSet, function(val, key) { + Object.keys(stopSet).forEach(function(key) { changesAlreadyMade[this.scrapeBaseID(key)] = true; }, this); var uniqueIDs = {}; // resolve the commits we will rebase - return _.filter(toRebaseRough, function(commit) { + return toRebaseRough.filter(function(commit) { // no merge commits, unless we preserve if (commit.get('parents').length !== 1 && !options.preserveMerges) { return false; } // we ALSO need to throw out commits that will do the same changes. like - // if the upstream set has a commit C4 and we have C4', we dont rebase the C4' again. + // if the upstream set has a commit C4 and we have C4', we don't rebase the C4' again. var baseID = this.scrapeBaseID(commit.get('id')); if (changesAlreadyMade[baseID]) { return false; @@ -2344,7 +2361,7 @@ GitEngine.prototype.filterRebaseCommits = function( GitEngine.prototype.getRebasePreserveMergesParents = function(oldCommit) { var oldParents = oldCommit.get('parents'); - return _.map(oldParents, function(parent) { + return oldParents.map(function(parent) { var oldID = parent.get('id'); var newID = this.getMostRecentBumpedID(oldID); return this.refs[newID]; @@ -2406,7 +2423,7 @@ GitEngine.prototype.rebaseFinish = function( }.bind(this); // set up the promise chain - _.each(toRebase, function(commit) { + toRebase.forEach(function (commit) { chain = chain.then(function() { return chainStep(commit); }); @@ -2511,7 +2528,7 @@ GitEngine.prototype.checkout = function(idOrTarget) { GitEngine.prototype.forceBranch = function(branchName, where) { branchName = this.crappyUnescape(branchName); // if branchname doesn't exist... - if (!this.refs[branchName]) { + if (!this.doesRefExist(branchName)) { this.branch(branchName, where); } @@ -2561,7 +2578,7 @@ GitEngine.prototype.describe = function(ref) { // ok we need to BFS from start upwards until we hit a tag. but // first we need to get a reverse mapping from tag to commit var tagMap = {}; - _.each(this.tagCollection.toJSON(), function(tag) { + this.tagCollection.toJSON().forEach(function (tag) { tagMap[tag.target.get('id')] = tag.id; }); @@ -2733,7 +2750,7 @@ GitEngine.prototype.status = function() { lines.push(intl.str('git-status-readytocommit')); var msg = ''; - _.each(lines, function(line) { + lines.forEach(function (line) { msg += '# ' + line + '\n'; }); @@ -2748,37 +2765,26 @@ GitEngine.prototype.logWithout = function(ref, omitBranch) { this.log(ref, Graph.getUpstreamSet(this, omitBranch)); }; -GitEngine.prototype.log = function(ref, omitSet) { - // omit set is for doing stuff like git log branchA ^branchB - omitSet = omitSet || {}; - // first get the commit we referenced - var commit = this.getCommitFromRef(ref); +GitEngine.prototype.revlist = function(refs) { + var range = new RevisionRange(this, refs); - // then get as many far back as we can from here, order by commit date - var toDump = []; - var pQueue = [commit]; + // now go through and collect ids + var bigLogStr = range.formatRevisions(function(c) { + return c.id + '\n'; + }); - var seen = {}; + throw new CommandResult({ + msg: bigLogStr + }); +}; - while (pQueue.length) { - var popped = pQueue.shift(0); - if (seen[popped.get('id')] || omitSet[popped.get('id')]) { - continue; - } - seen[popped.get('id')] = true; - - toDump.push(popped); - - if (popped.get('parents') && popped.get('parents').length) { - pQueue = pQueue.concat(popped.get('parents')); - } - } +GitEngine.prototype.log = function(refs) { + var range = new RevisionRange(this, refs); // now go through and collect logs - var bigLogStr = ''; - _.each(toDump, function(c) { - bigLogStr += c.getLogEntry(); - }, this); + var bigLogStr = range.formatRevisions(function(c) { + return c.getLogEntry(); + }); throw new CommandResult({ msg: bigLogStr @@ -2787,7 +2793,7 @@ GitEngine.prototype.log = function(ref, omitSet) { GitEngine.prototype.getCommonAncestor = function(ancestor, cousin, dontThrow) { if (this.isUpstreamOf(cousin, ancestor) && !dontThrow) { - throw new Error('Dont use common ancestor if we are upstream!'); + throw new Error('Don\'t use common ancestor if we are upstream!'); } var upstreamSet = Graph.getUpstreamSet(this, ancestor); @@ -2801,7 +2807,7 @@ GitEngine.prototype.getCommonAncestor = function(ancestor, cousin, dontThrow) { } queue = queue.concat(here.get('parents')); } - throw new Error('something has gone very wrong... two nodes arent connected!'); + throw new Error('something has gone very wrong... two nodes aren\'t connected!'); }; GitEngine.prototype.isUpstreamOf = function(child, ancestor) { @@ -2831,7 +2837,7 @@ GitEngine.prototype.getDownstreamSet = function(ancestor) { var here = queue.pop(); var children = here.get('children'); - _.each(children, addToExplored); + children.forEach(addToExplored); } return exploredSet; }; @@ -2913,7 +2919,7 @@ var Branch = Ref.extend({ getBaseID: function() { if (!this.getIsRemote()) { - throw new Error('im not remote so cant get base'); + throw new Error('im not remote so can\'t get base'); } return this.get('id').replace(ORIGIN_PREFIX, ''); }, @@ -2943,30 +2949,27 @@ var Commit = Backbone.Model.extend({ }, getLogEntry: function() { - // for now we are just joining all these things with newlines which - // will get placed by paragraph tags. Not really a fan of this, but - // it's better than making an entire template and all that jazz return [ 'Author: ' + this.get('author'), 'Date: ' + this.get('createTime'), - '
', + '', this.get('commitMessage'), - '
', + '', 'Commit: ' + this.get('id') - ].join('\n' ) + '\n'; + ].join('
') + '\n'; }, getShowEntry: function() { // same deal as above, show log entry and some fake changes return [ - this.getLogEntry(), + this.getLogEntry().replace('\n', ''), 'diff --git a/bigGameResults.html b/bigGameResults.html', '--- bigGameResults.html', '+++ bigGameResults.html', '@@ 13,27 @@ Winner, Score', '- Stanfurd, 14-7', '+ Cal, 21-14' - ].join('\n') + '\n'; + ].join('
') + '\n'; }, validateAtInit: function() { @@ -3009,7 +3012,7 @@ var Commit = Backbone.Model.extend({ }, removeFromParents: function() { - _.each(this.get('parents'), function(parent) { + this.get('parents').forEach(function (parent) { parent.removeChild(this); }, this); }, @@ -3052,11 +3055,11 @@ var Commit = Backbone.Model.extend({ removeChild: function(childToRemove) { var newChildren = []; - _.each(this.get('children'), function(child) { + this.get('children').forEach(function (child) { if (child !== childToRemove) { newChildren.push(child); } - }, this); + }); this.set('children', newChildren); }, @@ -3069,7 +3072,7 @@ var Commit = Backbone.Model.extend({ this.validateAtInit(); this.addNodeToVisuals(); - _.each(this.get('parents'), function(parent) { + (this.get('parents') || []).forEach(function (parent) { parent.get('children').push(this); this.addEdgeToVisuals(parent); }, this); @@ -3087,6 +3090,102 @@ var Tag = Ref.extend({ } }); +function RevisionRange(engine, specifiers) { + this.engine = engine; + this.tipsToInclude = []; + this.tipsToExclude = []; + this.includedRefs = {}; + this.excludedRefs = {}; + this.revisions = []; + + this.processSpecifiers(specifiers); +} + +var rangeRegex = /^(.*)\.\.(.*)$/; + +RevisionRange.prototype.processAsRange = function(specifier) { + var match = specifier.match(rangeRegex); + if(!match) { + return false; + } + this.tipsToExclude.push(match[1]); + this.tipsToInclude.push(match[2]); + return true; +}; + +RevisionRange.prototype.processAsExclusion = function(specifier) { + if(!specifier.startsWith('^')) { + return false; + } + this.tipsToExclude.push(specifier.slice(1)); + return true; +}; + +RevisionRange.prototype.processAsInclusion = function(specifier) { + this.tipsToInclude.push(specifier); + return true; +}; + +RevisionRange.prototype.processSpecifiers = function(specifiers) { + var self = this; + var processors = [ + this.processAsRange, + this.processAsExclusion + ]; + + specifiers.forEach(function(specifier) { + if(!processors.some(function(processor) { return processor.bind(self)(specifier); })) { + self.processAsInclusion(specifier); + } + }); + + this.tipsToExclude.forEach(function(exclusion) { + self.addExcluded(Graph.getUpstreamSet(self.engine, exclusion)); + }); + + this.tipsToInclude.forEach(function(inclusion) { + self.addIncluded(Graph.getUpstreamSet(self.engine, inclusion)); + }); + + var includedKeys = Array.from(Object.keys(self.includedRefs)); + + self.revisions = includedKeys.map(function(revision) { + return self.engine.resolveStringRef(revision); + }); + self.revisions.sort(self.engine.dateSortFunc); + self.revisions.reverse(); +}; + +RevisionRange.prototype.isExcluded = function(revision) { + return this.excludedRefs.hasOwnProperty(revision); +}; + +RevisionRange.prototype.addExcluded = function(setToExclude) { + var self = this; + Object.keys(setToExclude).forEach(function(toExclude) { + if(!self.isExcluded(toExclude)) { + self.excludedRefs[toExclude] = true; + } + }); +}; + +RevisionRange.prototype.addIncluded = function(setToInclude) { + var self = this; + Object.keys(setToInclude).forEach(function(toInclude) { + if(!self.isExcluded(toInclude)) { + self.includedRefs[toInclude] = true; + } + }); +}; + +RevisionRange.prototype.formatRevisions = function(revisionFormatter) { + var output = ""; + this.revisions.forEach(function(c) { + output += revisionFormatter(c); + }); + return output; +}; + exports.GitEngine = GitEngine; exports.Commit = Commit; exports.Branch = Branch; diff --git a/src/js/graph/index.js b/src/js/graph/index.js index 49285de0..2eaf6cab 100644 --- a/src/js/graph/index.js +++ b/src/js/graph/index.js @@ -1,5 +1,3 @@ -var _ = require('underscore'); - function invariant(truthy, reason) { if (!truthy) { throw new Error(reason); @@ -44,7 +42,7 @@ var Graph = { if (type == 'HEAD') { var headJSON = tree.HEAD; - var HEAD = new Ref(_.extend( + var HEAD = new Ref(Object.assign( tree.HEAD, { target: this.getOrMakeRecursive(tree, createdSoFar, headJSON.target) @@ -57,7 +55,7 @@ var Graph = { if (type == 'branch') { var branchJSON = tree.branches[objID]; - var branch = new Branch(_.extend( + var branch = new Branch(Object.assign( tree.branches[objID], { target: this.getOrMakeRecursive(tree, createdSoFar, branchJSON.target) @@ -70,7 +68,7 @@ var Graph = { if (type == 'tag') { var tagJSON = tree.tags[objID]; - var tag = new Tag(_.extend( + var tag = new Tag(Object.assign( tree.tags[objID], { target: this.getOrMakeRecursive(tree, createdSoFar, tagJSON.target) @@ -85,11 +83,11 @@ var Graph = { var commitJSON = tree.commits[objID]; var parentObjs = []; - _.each(commitJSON.parents, function(parentID) { + commitJSON.parents.forEach(function(parentID) { parentObjs.push(this.getOrMakeRecursive(tree, createdSoFar, parentID)); }, this); - var commit = new Commit(_.extend( + var commit = new Commit(Object.assign( commitJSON, { parents: parentObjs, @@ -143,7 +141,7 @@ var Graph = { var here = queue.pop(); var rents = here.get('parents'); - _.each(rents, addToExplored); + (rents || []).forEach(addToExplored); } return exploredSet; }, @@ -151,7 +149,7 @@ var Graph = { getUniqueObjects: function(objects) { var unique = {}; var result = []; - _.forEach(objects, function(object) { + objects.forEach(function(object) { if (unique[object.id]) { return; } diff --git a/src/js/graph/treeCompare.js b/src/js/graph/treeCompare.js index 0cf71286..f01cf457 100644 --- a/src/js/graph/treeCompare.js +++ b/src/js/graph/treeCompare.js @@ -54,6 +54,10 @@ TreeCompare.dispatchShallow = function(levelBlob, goalTreeString, treeToCompare) return TreeCompare.compareBranchWithinTrees( treeToCompare, goalTreeString, 'master' ); + case !!levelBlob.compareAllBranchesAndEnforceBranchCleanup: + return TreeCompare.compareAllBranchesAndEnforceBranchCleanup( + treeToCompare, goalTreeString + ); case !!levelBlob.compareOnlyBranches: return TreeCompare.compareAllBranchesWithinTrees( treeToCompare, goalTreeString @@ -78,85 +82,103 @@ TreeCompare.dispatchShallow = function(levelBlob, goalTreeString, treeToCompare) }; // would love to have copy properties here.. :( -TreeCompare.compareAllBranchesWithinTreesAndHEAD = function(treeA, treeB) { - treeA = this.convertTreeSafe(treeA); - treeB = this.convertTreeSafe(treeB); +TreeCompare.compareAllBranchesWithinTreesAndHEAD = function(treeToCompare, goalTree) { + treeToCompare = this.convertTreeSafe(treeToCompare); + goalTree = this.convertTreeSafe(goalTree); // also compare tags!! for just one level - return treeA.HEAD.target === treeB.HEAD.target && - this.compareAllBranchesWithinTrees(treeA, treeB) && - this.compareAllTagsWithinTrees(treeA, treeB); + return treeToCompare.HEAD.target === goalTree.HEAD.target && + this.compareAllBranchesWithinTrees(treeToCompare, goalTree) && + this.compareAllTagsWithinTrees(treeToCompare, goalTree); }; -TreeCompare.compareAllBranchesWithinTrees = function(treeA, treeB) { - treeA = this.convertTreeSafe(treeA); - treeB = this.convertTreeSafe(treeB); +TreeCompare.compareAllBranchesAndEnforceBranchCleanup = function(treeToCompare, goalTree) { + treeToCompare = this.convertTreeSafe(treeToCompare); + goalTree = this.convertTreeSafe(goalTree); - var allBranches = _.extend( + // Unlike compareAllBranchesWithinTrees, here we consider both the branches + // in the goalTree and the branches in the treeToCompare. This means that + // we enfoce that you clean up any branches that you have locally that + // the goal does not have. this is helpful when we want to verify that you + // have deleted branch, for instance. + var allBranches = Object.assign( {}, - treeA.branches, - treeB.branches + treeToCompare.branches, + goalTree.branches ); - - var result = true; - _.uniq(allBranches, function(info, branch) { - result = result && this.compareBranchWithinTrees(treeA, treeB, branch); - }, this); - return result; + return Object.keys(allBranches).every(function(branch) { + return this.compareBranchWithinTrees(treeToCompare, goalTree, branch); + }.bind(this)); }; -TreeCompare.compareAllTagsWithinTrees = function(treeA, treeB) { - treeA = this.convertTreeSafe(treeA); - treeB = this.convertTreeSafe(treeB); - this.reduceTreeFields([treeA, treeB]); - return _.isEqual(treeA.tags, treeB.tags); +TreeCompare.compareAllBranchesWithinTrees = function(treeToCompare, goalTree) { + treeToCompare = this.convertTreeSafe(treeToCompare); + goalTree = this.convertTreeSafe(goalTree); + + /** + * Disclaimer / reminder!! We only care about branches in the goal tree; + * if you have extra branches in your source tree thats ok. but that means + * the arguments here are important -- always call this function with + * goalTree being the latter argument, since we will discard extra branches + * from treeToCompare (the first argument). + */ + return Object.keys(goalTree.branches).every(function(branch) { + return this.compareBranchWithinTrees(treeToCompare, goalTree, branch); + }.bind(this)); }; -TreeCompare.compareBranchesWithinTrees = function(treeA, treeB, branches) { +TreeCompare.compareAllTagsWithinTrees = function(treeToCompare, goalTree) { + treeToCompare = this.convertTreeSafe(treeToCompare); + goalTree = this.convertTreeSafe(goalTree); + this.reduceTreeFields([treeToCompare, goalTree]); + + return _.isEqual(treeToCompare.tags, goalTree.tags); +}; + +TreeCompare.compareBranchesWithinTrees = function(treeToCompare, goalTree, branches) { var result = true; - _.each(branches, function(branchName) { - result = result && this.compareBranchWithinTrees(treeA, treeB, branchName); + branches.forEach(function(branchName) { + result = result && this.compareBranchWithinTrees(treeToCompare, goalTree, branchName); }, this); return result; }; -TreeCompare.compareBranchWithinTrees = function(treeA, treeB, branchName) { - treeA = this.convertTreeSafe(treeA); - treeB = this.convertTreeSafe(treeB); - this.reduceTreeFields([treeA, treeB]); +TreeCompare.compareBranchWithinTrees = function(treeToCompare, goalTree, branchName) { + treeToCompare = this.convertTreeSafe(treeToCompare); + goalTree = this.convertTreeSafe(goalTree); + this.reduceTreeFields([treeToCompare, goalTree]); - var recurseCompare = this.getRecurseCompare(treeA, treeB); - var branchA = treeA.branches[branchName]; - var branchB = treeB.branches[branchName]; + var recurseCompare = this.getRecurseCompare(treeToCompare, goalTree); + var branchA = treeToCompare.branches[branchName]; + var branchB = goalTree.branches[branchName]; return _.isEqual(branchA, branchB) && - recurseCompare(treeA.commits[branchA.target], treeB.commits[branchB.target]); + recurseCompare(treeToCompare.commits[branchA.target], goalTree.commits[branchB.target]); }; -TreeCompare.compareAllBranchesWithinTreesHashAgnostic = function(treeA, treeB) { - treeA = this.convertTreeSafe(treeA); - treeB = this.convertTreeSafe(treeB); - this.reduceTreeFields([treeA, treeB]); +TreeCompare.compareAllBranchesWithinTreesHashAgnostic = function(treeToCompare, goalTree) { + treeToCompare = this.convertTreeSafe(treeToCompare); + goalTree = this.convertTreeSafe(goalTree); + this.reduceTreeFields([treeToCompare, goalTree]); - var allBranches = _.extend( + var allBranches = Object.assign( {}, - treeA.branches, - treeB.branches + treeToCompare.branches, + goalTree.branches ); - var branchNames = []; - _.each(allBranches, function(obj, name) { branchNames.push(name); }); + var branchNames = Object.keys(allBranches || {}); - return this.compareBranchesWithinTreesHashAgnostic(treeA, treeB, branchNames); + return this.compareBranchesWithinTreesHashAgnostic(treeToCompare, goalTree, branchNames); }; -TreeCompare.compareBranchesWithinTreesHashAgnostic = function(treeA, treeB, branches) { +TreeCompare.compareBranchesWithinTreesHashAgnostic = function(treeToCompare, goalTree, branches) { // we can't DRY unfortunately here because we need a special _.isEqual function // for both the recursive compare and the branch compare - treeA = this.convertTreeSafe(treeA); - treeB = this.convertTreeSafe(treeB); - this.reduceTreeFields([treeA, treeB]); + treeToCompare = this.convertTreeSafe(treeToCompare); + goalTree = this.convertTreeSafe(goalTree); + this.reduceTreeFields([treeToCompare, goalTree]); // get a function to compare branch objects without hashes var compareBranchObjs = function(branchA, branchB) { @@ -164,31 +186,32 @@ TreeCompare.compareBranchesWithinTreesHashAgnostic = function(treeA, treeB, bran return false; } - // dont mess up the rest of comparison - branchA = _.clone(branchA); - branchB = _.clone(branchB); + // don't mess up the rest of comparison + branchA = Object.assign({}, branchA); + branchB = Object.assign({}, branchB); branchA.target = this.getBaseRef(branchA.target); branchB.target = this.getBaseRef(branchB.target); return _.isEqual(branchA, branchB); }.bind(this); // and a function to compare recursively without worrying about hashes - var recurseCompare = this.getRecurseCompareHashAgnostic(treeA, treeB); + var recurseCompare = this.getRecurseCompareHashAgnostic(treeToCompare, goalTree); var result = true; - _.each(branches, function(branchName) { - var branchA = treeA.branches[branchName]; - var branchB = treeB.branches[branchName]; + branches.forEach(function(branchName) { + var branchA = treeToCompare.branches[branchName]; + var branchB = goalTree.branches[branchName]; result = result && compareBranchObjs(branchA, branchB) && - recurseCompare(treeA.commits[branchA.target], treeB.commits[branchB.target]); + recurseCompare(treeToCompare.commits[branchA.target], goalTree.commits[branchB.target]); }, this); return result; }; TreeCompare.evalAsserts = function(tree, assertsPerBranch) { var result = true; - _.each(assertsPerBranch, function(asserts, branchName) { + Object.keys(assertsPerBranch).forEach(function(branchName) { + var asserts = assertsPerBranch[branchName]; result = result && this.evalAssertsOnBranch(tree, branchName, asserts); }, this); return result; @@ -217,7 +240,7 @@ TreeCompare.evalAssertsOnBranch = function(tree, branchName, asserts) { } var result = true; - _.each(asserts, function(assert) { + asserts.forEach(function(assert) { try { result = result && assert(data); } catch (err) { @@ -251,7 +274,7 @@ TreeCompare.getNumHashes = function(ref) { return func(results); } } - throw new Error('couldnt parse ref ' + ref); + throw new Error('couldn\'t parse ref ' + ref); }; TreeCompare.getBaseRef = function(ref) { @@ -263,14 +286,14 @@ TreeCompare.getBaseRef = function(ref) { return 'C' + bits[1]; }; -TreeCompare.getRecurseCompareHashAgnostic = function(treeA, treeB) { +TreeCompare.getRecurseCompareHashAgnostic = function(treeToCompare, goalTree) { // here we pass in a special comparison function to pass into the base // recursive compare. // some buildup functions var getStrippedCommitCopy = function(commit) { if (!commit) { return {}; } - return _.extend( + return Object.assign( {}, commit, { @@ -286,10 +309,10 @@ TreeCompare.getRecurseCompareHashAgnostic = function(treeA, treeB) { getStrippedCommitCopy(commitB) ); }; - return this.getRecurseCompare(treeA, treeB, {isEqual: isEqual}); + return this.getRecurseCompare(treeToCompare, goalTree, {isEqual: isEqual}); }; -TreeCompare.getRecurseCompare = function(treeA, treeB, options) { +TreeCompare.getRecurseCompare = function(treeToCompare, goalTree, options) { options = options || {}; // we need a recursive comparison function to bubble up the branch @@ -305,17 +328,17 @@ TreeCompare.getRecurseCompare = function(treeA, treeB, options) { // so the index lookup is valid. for merge commits this will duplicate some of the // checking (because we aren't doing graph search) but it's not a huge deal var maxNumParents = Math.max(commitA.parents.length, commitB.parents.length); - _.each(_.range(maxNumParents), function(index) { + for (var index = 0; index < maxNumParents; index++) { var pAid = commitA.parents[index]; var pBid = commitB.parents[index]; - // if treeA or treeB doesn't have this parent, + // if treeToCompare or goalTree doesn't have this parent, // then we get an undefined child which is fine when we pass into _.isEqual - var childA = treeA.commits[pAid]; - var childB = treeB.commits[pBid]; + var childA = treeToCompare.commits[pAid]; + var childB = goalTree.commits[pBid]; result = result && recurseCompare(childA, childB); - }, this); + } // if each of our children recursively are equal, we are good return result; }; @@ -327,9 +350,10 @@ TreeCompare.lowercaseTree = function(tree) { tree.HEAD.target = tree.HEAD.target.toLocaleLowerCase(); } - var branches = tree.branches; + var branches = tree.branches || {}; tree.branches = {}; - _.each(branches, function(obj, name) { + Object.keys(branches).forEach(function(name) { + var obj = branches[name]; obj.id = obj.id.toLocaleLowerCase(); tree.branches[name.toLocaleLowerCase()] = obj; }); @@ -377,8 +401,9 @@ TreeCompare.reduceTreeFields = function(trees) { tags: {} }; - _.each(trees, function(tree) { - _.each(treeDefaults, function(val, key) { + trees.forEach(function(tree) { + Object.keys(treeDefaults).forEach(function(key) { + var val = treeDefaults[key]; if (tree[key] === undefined) { tree[key] = val; } @@ -388,10 +413,11 @@ TreeCompare.reduceTreeFields = function(trees) { // this function saves only the specified fields of a tree var saveOnly = function(tree, treeKey, saveFields, sortFields) { var objects = tree[treeKey]; - _.each(objects, function(obj, objKey) { + Object.keys(objects).forEach(function(objKey) { + var obj = objects[objKey]; // our blank slate to copy over var blank = {}; - _.each(saveFields, function(field) { + saveFields.forEach(function(field) { if (obj[field] !== undefined) { blank[field] = obj[field]; } else if (defaults[field] !== undefined) { @@ -399,7 +425,7 @@ TreeCompare.reduceTreeFields = function(trees) { } }); - _.each(sortFields, function(field) { + Object.values(sortFields || {}).forEach(function(field) { // also sort some fields if (obj[field]) { obj[field].sort(); @@ -410,7 +436,7 @@ TreeCompare.reduceTreeFields = function(trees) { }); }; - _.each(trees, function(tree) { + trees.forEach(function(tree) { saveOnly(tree, 'commits', commitSaveFields, commitSortFields); saveOnly(tree, 'branches', branchSaveFields); saveOnly(tree, 'tags', tagSaveFields); @@ -425,15 +451,15 @@ TreeCompare.reduceTreeFields = function(trees) { }, this); }; -TreeCompare.compareTrees = function(treeA, treeB) { - treeA = this.convertTreeSafe(treeA); - treeB = this.convertTreeSafe(treeB); +TreeCompare.compareTrees = function(treeToCompare, goalTree) { + treeToCompare = this.convertTreeSafe(treeToCompare); + goalTree = this.convertTreeSafe(goalTree); // now we need to strip out the fields we don't care about, aka things // like createTime, message, author - this.reduceTreeFields([treeA, treeB]); + this.reduceTreeFields([treeToCompare, goalTree]); - return _.isEqual(treeA, treeB); + return _.isEqual(treeToCompare, goalTree); }; module.exports = TreeCompare; diff --git a/src/js/intl/checkStrings.js b/src/js/intl/checkStrings.js index 4a1c5212..f7e473d0 100644 --- a/src/js/intl/checkStrings.js +++ b/src/js/intl/checkStrings.js @@ -1,54 +1,33 @@ -var sys = require('sys'); +var { join } = require('path'); +var { readFileSync } = require('fs'); + var util = require('../util'); -var child_process = require('child_process'); -var strings = require('../intl/strings').strings; +var { strings } = require('../intl/strings'); -var searchCommand = 'grep -C 2 -r "intl.str(" ../../'; -var genBadKeyCommand = function(key) { - return 'grep -r "' + key + '" ../../'; -}; +var easyRegex = /intl\.str\(\s*'([a-zA-Z\-]+)'/g; -var easyRegex = /intl.str\('([a-zA-Z\-]+)'/g; -var hardRegex = /\s+'([a-z\-]+)',/g; +var allKetSet = new Set(Object.keys(strings)); +allKetSet.delete('error-untranslated'); // used in ./index.js -var findKey = function(badKey) { - child_process.exec(genBadKeyCommand(badKey), function(err, output) { - console.log(output); - }); -}; - -var goodKeys = 0; +var goodKeySet = new Set(); var validateKey = function(key) { if (!strings[key]) { console.log('NO KEY for: "', key, '"'); - findKey(key); } else { - goodKeys++; + goodKeySet.add(key); + allKetSet.delete(key); } }; -var processLines = function(lines) { - lines.forEach(function(line) { - var results = easyRegex.exec(line); - if (results && results[1]) { - validateKey(results[1]); - return; - } - // could be a multi-liner - results = hardRegex.exec(line); - if (results && results[1]) { - validateKey(results[1]); +if (!util.isBrowser()) { + util.readDirDeep(join(__dirname, '../../')).forEach(function(path) { + var content = readFileSync(path); + var match; + while (match = easyRegex.exec(content)) { + validateKey(match[1]); } }); -}; - -if (!util.isBrowser()) { - child_process.exec( - searchCommand, - function(err, output) { - processLines(output.split('\n')); - console.log(goodKeys + ' good keys found!'); - } - ); + console.log(goodKeySet.size, ' good keys found!'); + console.log(allKetSet.size, ' keys did not use!'); + console.log(allKetSet); } - diff --git a/src/js/intl/index.js b/src/js/intl/index.js index 9a1e315c..8247429a 100644 --- a/src/js/intl/index.js +++ b/src/js/intl/index.js @@ -11,7 +11,7 @@ var fallbackMap = { // lets change underscores template settings so it interpolates // things like "{branchName} does not exist". -var templateSettings = _.clone(_.templateSettings); +var templateSettings = Object.assign({}, _.templateSettings); templateSettings.interpolate = /\{(.+?)\}/g; var template = exports.template = function(str, params) { return _.template(str, params, templateSettings); @@ -57,7 +57,7 @@ var str = exports.str = function(key, params) { var getIntlKey = exports.getIntlKey = function(obj, key, overrideLocale) { if (!obj || !obj[key]) { - throw new Error('that key ' + key + 'doesnt exist in this blob' + obj); + throw new Error('that key ' + key + 'doesn\'t exist in this blob' + obj); } if (!obj[key][getDefaultLocale()]) { console.warn( @@ -98,7 +98,7 @@ exports.getStartDialog = function(level) { var startDialog = getIntlKey(level, 'startDialog'); if (startDialog) { return startDialog; } - // this level translation isnt supported yet, so lets add + // this level translation isn't supported yet, so lets add // an alert to the front and give the english version. var errorAlert = { type: 'ModalAlert', @@ -106,7 +106,8 @@ exports.getStartDialog = function(level) { markdown: str('error-untranslated') } }; - var startCopy = _.clone( + var startCopy = Object.assign( + {}, level.startDialog[getDefaultLocale()] || level.startDialog ); startCopy.childViews.unshift(errorAlert); diff --git a/src/js/intl/strings.js b/src/js/intl/strings.js index a96261b8..2154ea35 100755 --- a/src/js/intl/strings.js +++ b/src/js/intl/strings.js @@ -4,16 +4,21 @@ exports.strings = { '__desc__': 'One of the lines in the next level dialog', 'ja': '最後のレベルをクリアしました!すごい!!', 'en_US': 'Wow! You finished the last level, great!', - 'de_DE': 'Wow! Du hast den letzten Level gelöst, super!', + 'de_DE': 'Wow! Du hast das letzte Level gelöst, super!', 'zh_CN': 'Wow!你通关了!', 'zh_TW': '我的天啊!您解開了最後一關,太強了!', 'es_AR': '¡Ea! Terminaste el último nivel, ¡genial!', + 'es_MX': '¡Enhorabuena! Terminaste el último nivel, ¡genial!', 'es_ES': '¡Felicitaciones! Terminaste el último nivel!', 'pt_BR': 'Uia! Você terminou o último nível, massa!', + 'gl' : '¡Yeeeha! Remataches o derradeiro nivel, ¡a tope!', 'fr_FR': 'Félicitations, vous avez réussi le dernier niveau !', 'ru_RU': 'Вау! Вы прошли последний уровень, отлично!', 'uk': 'Вау! Ти пройшов останній рівень, круто!', - 'ko': '와우! 마지막 레벨까지 마쳤습니다. 멋지네요!' + 'ko': '와우! 마지막 레벨까지 마쳤습니다. 멋지네요!', + 'vi': 'Wao! Bạn đã phá đảo, quá tuyệt!', + 'sl_SI': 'Wow! Končal si zadnjo stopnjo, fantastično!', + 'pl': 'Wow! Ukończono ostatni poziom, świetnie!' }, /////////////////////////////////////////////////////////////////////////// 'finish-dialog-next': { @@ -24,12 +29,17 @@ exports.strings = { 'zh_CN': '要不要试试下一关 *“{nextLevel}”*?', 'zh_TW': '下一關是*「{nextLevel}」*,您要繼續闖關嗎?', 'es_AR': '¿Querés seguir con *"{nextLevel}"*, el próximo nivel?', - 'es_ES': '¿Quieres seguir al nivel *"{nextLevel}"*, el próximo nivel?', + 'es_MX': '¿Quieres seguir con *"{nextLevel}"*, el próximo nivel?', + 'es_ES': '¿Quieres pasar al nivel *"{nextLevel}"*, el próximo nivel?', 'pt_BR': 'Você gostaria de ir para o próximo nível: *"{nextLevel}"*?', + 'gl' : '¿Gustaríache ir o seguinte nivel: *"{nextLevel}"*?', 'fr_FR': 'Voulez-vous passer à *"{nextLevel}"*, le prochain niveau ?', 'ru_RU': 'Хотите перейти на следующий уровень: *"{nextLevel}"*?', 'uk': 'Хочеш перейти на наступний рівень -- *"{nextLevel}"*?', - 'ko': '다음 레벨로 넘어갈까요? 레벨 *"{nextLevel}"*' + 'ko': '다음 레벨로 넘어갈까요? 레벨 *"{nextLevel}"*', + 'vi': 'Bạn có muốn chuyển sang cấp độ tiếp: *"{nextLevel}"* không?', + 'sl_SI': 'Bi rad nadaljeval na *"{nextLevel}"*, naslednjo stopnjo?', + 'pl': 'Czy chcesz przejść do następnego poziomu - *"{nextLevel}"*?' }, /////////////////////////////////////////////////////////////////////////// 'finish-dialog-win': { @@ -41,11 +51,16 @@ exports.strings = { 'zh_CN': '太强了!你的答案符合标准答案甚至更好。', 'zh_TW': '太強了,您的答案符合我們的預期甚至更好!', 'es_AR': '¡Fabuloso! Igualaste o superaste nuestra solución.', + 'es_MX': '¡Fabuloso! Igualaste o superaste nuestra solución.', 'es_ES': '¡Fabuloso! Igualaste o superaste nuestra solución.', + 'gl' : '¡Fabuloso! Fixécholo igual ou mellor ca nosa solución.', 'fr_FR': 'Fabuleux ! Votre solution a égalé ou surpassé notre solution.', 'ru_RU': 'Отлично! Ваше решение соответствует или превосходит наше.', 'uk': 'Чудово! Твій розв’язок на рівні або кращий від нашого.', - 'ko': '멋져요! 우리의 해답과 일치하거나 우리보다 좀 더 나은 해답입니다.' + 'ko': '멋져요! 우리의 해답과 일치하거나 우리보다 좀 더 나은 해답입니다.', + 'vi': 'Tuyệt vời! Đáp án của bạn đạt chuẩn thâm chí có thể tốt hơn.', + 'sl_SI': 'Bravo! Izenačil ali celo presegel si našo rešitev.', + 'pl': 'Niesamowite! Rozwiązałeś zadanie w ten sam sposób lub lepiej.' }, /////////////////////////////////////////////////////////////////////////// 'finish-dialog-lose': { @@ -56,12 +71,17 @@ exports.strings = { 'zh_CN': '试试看你能否在 {best} 步之内搞定 :D', 'zh_TW': '試試看您是否能在 {best} 步内搞定 :D', 'es_AR': 'Fijate si podés bajarlo a usar sólo {best} comandos :D', + 'es_MX': 'Fíjate si puedes bajarlo a usar sólo {best} comandos :D', 'es_ES': 'Trata de usar sólo {best} comandos :D', 'pt_BR': 'Veja se consegue reduzir para somente {best} :D', + 'gl' : 'Mira se consigues reducir a solo {best} :D', 'fr_FR': 'Voyons si vous pouvez descendre à {best} :D', 'ru_RU': 'Попробуйте, может вы сможете уложиться в {best} : D', 'uk': 'Спробуй, можливо ти зможеш вкластися в {best} кроків :D', - 'ko': '{best}회로 줄일 수 있다면 해보세요. :D' + 'ko': '{best}회로 줄일 수 있다면 해보세요. :D', + 'vi': 'Thử xem bạn có thể giảm xuống {best} không? :D', + 'sl_SI': 'Misliš da lahko spraviš rešitev na {best}? :D', + 'pl': 'Sprawdź, czy dasz radę to zrobić w {best} krokach :D' }, /////////////////////////////////////////////////////////////////////////// 'hg-prune-tree': { @@ -70,13 +90,18 @@ exports.strings = { 'zh_CN': '注意! Mercurial 会进行主动垃圾回收,需要将你的提交树縮小。', 'zh_TW': '注意! Mercurial 會積極地做垃圾收集,而且會因此把你的 tree 給縮小。', 'es_AR': '¡Cuidado! Mercurial hace garbage collection agresivamente y necesita eliminar tu árbol', - 'es_ES': '¡Cuidado! Mercurial hace la colección de basura agresivamente (para administrar memoria) y necesita podar tu árbol.', + 'es_MX': '¡Cuidado! Mercurial hace garbage collection agresivamente y necesita eliminar tu árbol', + 'es_ES': '¡Cuidado! Mercurial hace la recolección de basura agresivamente (para administrar memoria) y necesita podar tu árbol.', 'pt_BR': 'Cuidado! O Mercurial faz coleção de lixo agressiva e precisa prunar sua árvore', + 'gl' : '¡Coidado! Mercurial fai que recolección de lixo agresivamente (para limpar memoria) e precisa podar a túa árbore.', 'fr_FR': 'Attention, Mercurial supprime de façon agressive et nécessite un prune du repository', 'de_DE': 'Achtung! Mercurial macht aggressive Garbage Collection und muss daher deinen Baum reduzieren', 'ru_RU': 'Внимание! Mercurial использует агрессивный сборщик мусора и обрезает ваше дерево', 'uk': 'Увага! Mercurial агресивно збирає сміття й може обрізати твоє дерево ', - 'ko': '주의! Mercurial은 공격적으로 가비지 컬렉션을 수행하므로 트리를 정리할 필요가 있습니다.' + 'ko': '주의! Mercurial은 공격적으로 가비지 컬렉션을 수행하므로 트리를 정리할 필요가 있습니다.', + 'vi': 'Cảnh báo! Mercurial cần thực hiện thu gom rác và thu nhỏ cây lịch sử của bạn.', + 'sl_SI': 'Opozorilo! Mercurial ima agresivno politiko garbage collectiona in bo obrezal vaše drevo', + 'pl': 'Ostrzeżenie! Mercurial prowadzi agresywną kolekcję śmieci i dlatego musi przycinać Twoje drzewo' }, /////////////////////////////////////////////////////////////////////////// 'hg-a-option': { @@ -85,13 +110,18 @@ exports.strings = { 'zh_TW': '對於這個 app 來說,-A 選項並不是必須的,只需要 commit 就好!', 'zh_CN': '对本 App 而言,-A 选项并非必须项,直接 commit 就好!', 'es_AR': 'La opción -A no es necesaria para esta aplicación, simplemente hacé commit', + 'es_MX': 'La opción -A no es necesaria para ésta aplicación, simplemente se hace commit', 'es_ES': 'La opción -A no se necesita para este aplicación, sólo hace un commit!', 'pt_BR': 'A opção -A não é necessária para este aplicativo, simplesmente faça commit', + 'gl' : 'A opción -A non se necesita para este aplicativo, ¡fai só un commit!', 'de_DE': 'Die Option -A wird in dieser Anwendung nicht benötigt, committe einfach!', - 'fr_FR': 'L\'option -A n\'est pas nécessaire pour cette application, simplemer commiter', + 'fr_FR': 'L\'option -A n\'est pas nécessaire pour cette application, simplement commiter', 'ru_RU': 'Опция -A не требуется для этого приложения, просто сделайте коммит.', 'uk': 'Опція -A не потрібна для цього застосунку, можна просто комітити!', - 'ko': '이 앱에선 -A 옵션은 필요 없습니다. 그냥 커밋하세요!' + 'ko': '이 앱에선 -A 옵션은 필요 없습니다. 그냥 커밋하세요!', + 'vi': 'Không cần thiết phải dùng tùy chọn -A trên ứng dụng này, cứ commit là được!', + 'sl_SI': 'Opcija -A ni potrebna za to aplikacijo, samo commitaj!', + 'pl': 'Opcja -A nie jest wymagana w tej aplikacji, po prostu zrób `commit`!' }, /////////////////////////////////////////////////////////////////////////// 'hg-error-no-status': { @@ -100,13 +130,18 @@ exports.strings = { 'zh_CN': '本 App 没有 status 命令哦,因为根本没有 stage 缓存文件。可以用 hg summary 代替哦', 'zh_TW': '本 App 没有 status 命令哦,因为根本没有 stage 缓存文件。可以用 hg summary 代替哦', 'es_AR': 'No hay un comando status para esta aplicación, dado que no hay archivos que indexar. Probá hg summary, en cambio', - 'es_ES': 'No hay un comando status para esta aplicación, porque que no hay archivos que indexar. Prueba el comando hg summary, en cambio', + 'es_MX': 'No hay un comando status para esta aplicación, dado que no hay archivos que indexar. Prueba `hg summary`, en cambio', + 'es_ES': 'No hay un comando status para esta aplicación, porque no hay archivos que indexar. Prueba el comando hg summary', 'pt_BR': 'Não existe um comando status para este aplicativo, já que não há staging de arquivos. Tente hg summary', - 'fr_FR': 'Il n\'y a pas de commande status pour cette application, car il n\'y a pas de fichier stagé. Essayé hg summary à la place.', + 'gl' : 'Non hai un comando status para esta aplicación, xa que non hai ficheiros que indexar. Proba hg summary', + 'fr_FR': 'Il n\'y a pas de commande status pour cette application, car il n\'y a pas de fichier stagé. Essayez hg summary à la place.', 'de_DE': 'Es gibt keinen Befehl status in dieser Anwendung, da es kein Staging von Dateien gibt. Probier stattdessen hg summary', 'ru_RU': 'Команда status не поддерживается в этом приложении, так как здесь нет файлов. Попробуйте выполнить hg summary', 'uk': 'Команда status не підтримується в цьому застосунку, так як немає стейджингу(staging) файлів. Натомість спробуй hg summary ', - 'ko': '이 앱을 위한 상태 명령어는 없습니다. 왜냐하면 파일들의 스테이징이 없기 때문입니다. 대신 hg summary를 시도해보세요.' + 'ko': '이 앱을 위한 상태 명령어는 없습니다. 왜냐하면 파일들의 스테이징이 없기 때문입니다. 대신 hg summary를 시도해보세요.', + 'vi': 'Ứng dụng này không hỗ trợ lệnh `status` vì không có tệp nhớ đệm, thay vì đó hãy dùng lệnh `hg summary`', + 'sl_SI': 'Za to aplikacijo ni na voljo `status` ukaza, ker tu ni `stage-anja` datotek. Poizkusiš lahko `hg summary`', + 'pl' : 'W tej aplikacji nie ma polecenia `status`, ponieważ nie ma przemieszczania plików. Zamiast tego wypróbuj `hg summary`' }, /////////////////////////////////////////////////////////////////////////// 'hg-error-need-option': { @@ -115,13 +150,18 @@ exports.strings = { 'zh_CN': '我需要该命令使用 {option} 选项呢。', 'zh_TW': '我需要該命令使用 {option} 選項呢。', 'es_AR': '¡Necesito la opción {opcion} para ese comando!', + 'es_MX': '¡Necesito la opción {opcion} para ese comando!', 'es_ES': '¡Necesito la opción {opcion} para ese comando!', 'pt_BR': 'Eu preciso da opção {option} para esse comando!', + 'gl' : 'Preciso da opción {option} para ese comando!', 'fr_FR': 'J\'ai besoin de l\'option {option} pour cette commande', 'de_DE': 'Ich benötige die Option {option} für diesen Befehl!', 'ru_RU': 'Для этой команды требуется опция {option}', 'uk': 'Для цієї команди потрібна опція {option}', - 'ko': '나는 그 명령어를 위한 {option} 옵션이 필요합니다.' + 'ko': '나는 그 명령어를 위한 {option} 옵션이 필요합니다.', + 'vi': 'Câu lệnh đó cần tùy chọn {option}!', + 'sl_SI': 'Potrebujem opcijo {option} za ta ukaz!', + 'pl': 'Potrzebuję opcji {option} dla tego polecenia!' }, /////////////////////////////////////////////////////////////////////////// 'hg-error-log-no-follow': { @@ -130,13 +170,18 @@ exports.strings = { 'zh_CN': '暂不支持没有-f 选项的 hg log 命令,请补充 -f 选项吧', 'zh_TW': '暫不支持沒有-f 選項的 hg log 命令,請補充 -f 選項吧', 'es_AR': 'hg log sin el parámetro -f no está soportado, usá -f', + 'es_MX': 'hg log sin el parámetro -f no está soportado, usa -f', 'es_ES': 'Actualmente hg log sin -f no es compatible con esta aplicación. Usa -f.', 'pt_BR': 'hg log sem -f atualmente não é suportado, use -f', + 'gl' : 'hg log sen -f actulamente non é soportado, usa -f', 'fr_FR': 'hg log sans -f n\'est pas supporté', 'de_DE': 'hg log ohne -f wird aktuell nicht unterstützt, benutze bitte -f', 'ru_RU': 'hg log без опции -f в настоящий момент не поддерживается, используйте -f', 'uk': 'hg log без опції -f в данний момент не підтримується, використовуй -f', - 'ko': '-f가 없는 hg log는 현재 지원되지 않습니다. -f를 사용하세요.' + 'ko': '-f가 없는 hg log는 현재 지원되지 않습니다. -f를 사용하세요.', + 'vi': 'Hiện tại thì `hg log` mà không có tùy chọn -f chưa được hỗ trợ, hãy viết thêm -f.', + 'sl_SI': 'hg log brez -f trenutno ni podprt, uporabi -f', + 'pl': '`hg log` bez -f nie jest obecnie obsługiwany, użyj -f' }, /////////////////////////////////////////////////////////////////////////// 'git-status-detached': { @@ -146,12 +191,17 @@ exports.strings = { 'zh_CN': '游离的 Head(Detached head)!', 'zh_TW': '分離 Head!', 'es_AR': '¡Detached HEAD!', + 'es_MX': '¡HEAD separado! (Detached HEAD).', 'es_ES': '¡HEAD separado! (Detached HEAD).', 'pt_BR': 'Detached HEAD!', + 'gl' : '¡Detached HEAD!', 'fr_FR': 'head détaché !', 'ru_RU': 'Отделенный HEAD', 'uk': 'Відокремлений HEAD', - 'ko': '분리된 HEAD!' + 'ko': '분리된 HEAD!', + 'vi': 'HEAD bị tách biệt!', + 'sl_SI': 'Detached head!', + 'pl': 'Odłączono HEAD!' }, /////////////////////////////////////////////////////////////////////////// 'git-status-onbranch': { @@ -161,12 +211,17 @@ exports.strings = { 'zh_CN': '当前分支 {branch}', 'zh_TW': '切換到 branch {branch}', 'es_AR': 'En la rama {branch}', + 'es_MX': 'En la rama {branch}', 'es_ES': 'En la rama {branch}', 'pt_BR': 'No ramo {branch}', + 'gl' : 'Non na rama {branch}', 'fr_FR': 'Sur la branche {branch}', 'ru_RU': 'В ветке {branch}', 'uk': 'В гілці {branch}', - 'ko': '분기 지점 {branch}에서' + 'ko': '분기 지점 {branch}에서', + 'vi': 'Đang trên nhánh {branch}', + 'sl_SI': 'Na branchu {branch}', + 'pl': 'Na branch-u {branch}' }, /////////////////////////////////////////////////////////////////////////// 'git-status-readytocommit': { @@ -176,12 +231,17 @@ exports.strings = { 'zh_CN': '可以提交啦!(在这个程序中无须修改文件,一直可以提交)', 'zh_TW': '準備 commit!(在這個 demo 裡面可以一直 commit)', 'es_AR': '¡Listo para commitear! (como siempre en esta demo ;-) )', + 'es_MX': '¡Listo para hacer commit! (como siempre en ésta demo)', 'es_ES': '¡Listo para hacer un commit (como siempre en esta demo)!', 'pt_BR': 'Pronto para commitar! (como sempre neste demo ;-) )', + 'gl' : '¡Praparado para facer un commit (como sempre nesta demo ;-) )!', 'fr_FR': 'Prêt à commit ! (comme toujours dans cette démo)', 'ru_RU': 'Готово к коммиту! (как и всегда в этом демо)', 'uk': 'Готово до коміту! (як завжди в цьому демо)', - 'ko': '커밋을 준비하세요! (이 데모에서는 항상)' + 'ko': '커밋을 준비하세요! (이 데모에서는 항상)', + 'vi': 'Sẵn sàng để commit! (khi demo thì luôn có thể commit)', + 'sl_SI': 'Pripravljen za commit! (kot vedno v tem demotu)', + 'pl': 'Gotowy commit! (jak zawsze w tym demo)' }, /////////////////////////////////////////////////////////////////////////// 'git-dummy-msg': { @@ -192,12 +252,17 @@ exports.strings = { 'zh_CN': '快速提交。Coding 4ever!', 'zh_TW': '快速 commit。上啊熊!', 'es_AR': 'Otro commit más, y van...', + 'es_MX': 'Otro commit más, y van...', 'es_ES': 'Hagamos un commit. Atlanta, Georgia! Escucha WHATUPRG también.', 'pt_BR': 'Commitando.. Vai Timão!', + 'gl' : 'Mesturando.. ¡Alá imos!', 'fr_FR': 'Commit rapide. NoMaN Sux!', 'ru_RU': 'Быстрый коммит. А надо!', 'uk': 'Швидкий коміт. Динамо!', - 'ko': '빨리 커밋하세요!' + 'ko': '빨리 커밋하세요!', + 'vi': 'Commit luôn đi cho nóng!', + 'sl_SI': 'Hiter commit.', + 'pl': 'Szybki commit.' }, 'git-error-origin-fetch-uptodate': { '__desc__': 'One of the error messages for git', @@ -205,27 +270,37 @@ exports.strings = { 'de_DE': 'Bereits aktuell!', 'fr_FR': 'Déjà à jour', 'es_AR': 'Estás en la versión más reciente', + 'es_MX': 'Actualizado en la versión más reciente.', 'es_ES': 'Ya actualizado con la versión más reciente.', 'pt_BR': 'Já estamos na versão mais recente!', + 'gl' : 'Xa estamos actualizados ca versión máis recente', 'zh_TW': '已經是最新的了', 'zh_CN': '已经是最新的了', 'ru_RU': 'Уже обновлено!', 'uk': 'Вже оновлено!', - 'ko': '이미 최신 상태입니다!' + 'ko': '이미 최신 상태입니다!', + 'vi': 'Cập nhật mới nhất rồi!', + 'sl_SI': 'Že posodobljeno!', + 'pl': 'Już aktualne!' }, 'git-error-origin-fetch-no-ff': { '__desc__': 'One of the error messages for git', 'en_US': 'Your origin branch is out of sync with the remote branch and fetch cannot be performed', 'zh_CN': '你的 origin 仓库中的分支与远程分支的不同步了,无法执行 fetch 命令', 'zh_TW': '你的 origin 分支已經失去了與 remote 遠端分支的同步,所以無法執行 fetch 命令', - 'de_DE': 'Dein origin Branch ist nicht auf dem Stand des Remote Branch und fetch kann nicht ausgeführt werden', + 'de_DE': 'Dein origin Branch ist nicht auf dem Stand des Remote Branches und fetch kann nicht ausgeführt werden', 'es_AR': 'Tu rama origin está desincronizada con la rama remota, por lo que no se puede hacer el fetch', - 'es_ES': 'Tu rama origin no está sicronizada con la rama remota, así que un fetch no se puede realizar.', + 'es_MX': 'Tu rama origin está desincronizada con la rama remota, por lo que no se puede hacer el fetch', + 'es_ES': 'Tu rama origin no está sicronizada con la rama remota, así que el fetch no se puede realizar.', 'pt_BR': 'O fetch não pode ser realizado pois o ramo de origem está fora de sincronia com o ramo remoto', + 'gl' : 'O fetch non pode ser realizado xa que a rama de orixe non está sincronizada ca rama remota', 'fr_FR': 'Votre branche origin n\'est plus synchronisée avec la branche distante et fetch ne peut pas être appliqué. Essayez avec l\'option --force', 'ru_RU': 'Ваша origin ветка не синхронизирована с удаленной веткой, невозможно выполнить fetch', 'uk': 'Твоя гілка origin не синхронізована з віддаленою гілкою, неможливо виконати fetch', - 'ko': '당신의 오리진 브랜치가 원격 브랜치와 동기화되지 않았고, 패치를 실행할 수 없습니다.' + 'ko': '당신의 오리진 브랜치가 원격 브랜치와 동기화되지 않았고, 패치를 실행할 수 없습니다.', + 'vi': 'Nhánh của bạn không đồng bộ với nhánh remote nên lệnh fetch không thực thi được.', + 'sl_SI': 'Tvoj origin branch ni sinhroniziran z oddaljenim branchem, zato se fetch se ne more izvesti', + 'pl': 'Twój branch nie jest zsynchronizowany ze zdalny branch-em i nie można przeprowadzić pobierania' }, 'git-error-origin-push-no-ff': { '__desc__': 'One of the error messages for git', @@ -234,12 +309,17 @@ exports.strings = { 'zh_TW': '遠端倉庫與你的本地倉庫產生了分歧,故此上傳操作無法通過簡單地快進實現(因此你的 push 被拒絕了)。請 pull 下來遠端裡最新的更改,與本地合併之後再試一次。你可以通過 git pull 或 git pull --rebase 實現。', 'de_DE': 'Das entfernte Repository weicht von deinem lokalen Repository ab, daher können deine Änderungen nicht mit einem einfachen fast forward hochgeladen werden (und daher ist dein push abgelehnt worden). Bitte pull erst die neuen Änderungen in das lokale Repository, integriere sie in den Branch und versuch es nochmal. Das kannst du mit git pull oder git pull --rebase machen', 'es_AR': 'El repositorio remoto divergió de tu repositorio local, por lo que subir tus cambios no es un simple fast forward (y por eso se rechazó tu push). Por favor, hacé pull de los nuevos cambios en el repositorio remoto, incorporalos a esta rama y probá de nuevo. Podés hacerlo con git pull o git pull --rebase', - 'es_ES': 'El depósito remoto se ha desviado del depósito local. Subir cambios no es un avance rápido sencillo (por eso fue rechazado tu push). Por favor haz pull para descaragar los cambios en el depósito remoto para que los incorpores en la rama actual. Los cambios se pueden hacer pull con el comando "git pull" o "git pull--rebase"', + 'es_MX': 'El repositorio remoto divergió de tu repositorio local, por lo que subir tus cambios no es un simple fast forward (y por eso se rechazó tu push). Por favor, hacé pull de los nuevos cambios en el repositorio remoto, incorporalos a esta rama y prueba de nuevo. Puedes hacerlo con `git pull` o `git pull --rebase`', + 'es_ES': 'El repositorio remoto se ha desviado del repositorio local. Subir cambios no es un avance en cámara rápida (por eso fue rechazado tu push). Por favor haz pull para descargar los cambios en el repositorio remoto para que los incorpores en la rama actual. Los cambios se pueden hacer pull con el comando "git pull" o "git pull --rebase"', 'pt_BR': 'O repositório remoto divergiu do repositório local, então enviar suas mudanças não é um simples fast forward (e por isso seu push foi rejeitado). Por favor, faça pull das novas mudanças do repositório remoto, incorpore-os a este ramo, e tente novamente. Você pode fazê-lo com git pull ou git pull --rebase', + 'gl' : 'O repositorio remoto diverxe do teu repositorio local. Subir os cambios non é un fast-forward (avance rápido) e por iso foi rechazado o teu push. Por favor, fai un pull dos novos cambios do repositorio remoto e inclúeos na túa rama actual. Os cambios pódense facer co comando "git pull" ou "git pull --rebase"', 'fr_FR': 'Le dépôt distant a divergé de votre référentiel local, donc l\'envoi de vos modifications n\'est pas en simple avance rapide (et donc votre envoi a été rejeté). Veuillez récupérer les nouveaux changements depuis le dépôt distant, les intégrer dans cette branche, et essayez à nouveau. Vous pouvez le faire avec git pull ou git pull --rebase', 'ru_RU': 'Удаленный репозиторий разошелся с вашим локальным репозиторием, поэтому выгрузка ваших изменений не может быть в режиме fast forward (и следовательно ваш push будет отклонён). Пожалуйста, удалите изменения в удаленном репозитории которые, объедините их в эту ветку и попробуйте еще раз. Вы можете сделать это с помощью git pull или git pull --rebase', 'uk': 'Віддалений репозиторій розбігся з твоїм локальним репозиторієм, тому відвантаження твоїх змін не є простим fast forward (і тому твій push був відхилений). Будь-ласка, витягни зміни з віддаленого репозиторію, включи їх в цю гілку, й спробуй ще. Ти можеш зробити це за допомогою git pull чи git pull --rebase', - 'ko': '원격 레포지토리가 당신의 로컬 레포지토리에서 분기하므로, 변경 사항을 업데이트 하는것은 간단한 fast forward가 아닙니다(따라서 push가 거절될 것입니다.). 원격 레포지토리에서의 변경 사항을 내려 받아 이 브랜치에 합쳐라. 그리고 이걸 반복하라. 당신은 git pull 또는 git pull --rebase를 사용해 이를 수행할 수 있다.' + 'ko': '원격 레포지토리가 당신의 로컬 레포지토리에서 분기하므로, 변경 사항을 업데이트 하는것은 간단한 fast forward가 아닙니다(따라서 push가 거절될 것입니다.). 원격 레포지토리에서의 변경 사항을 내려 받아 이 브랜치에 합치고, 이를 반복하세요. 당신은 git pull 또는 git pull --rebase를 사용해 이를 수행할 수 있습니다.', + 'vi': 'Kho chứa từ xa có sự khác biệt với kho chứa cục bộ của bạn, nên không thể tự động (fast forward) cập nhật thay đổi của bạn (và vì thế hoạt động push của bạn bị từ chối). Vui lòng kéo về thay đổi từ kho chứa từ xa, kết nạp vào nhánh hiện tại, và thử lại lần nữa. Bạn có thể dùng lệnh `git pull` hoặc `git pull --rebase`', + 'sl_SI': 'Oddaljen repozitorij se je ločil od tvojega lokalnega repozitorija, zato nalaganje sprememb ni možno z `fast forward` opcijo (zato je bil `push` zavrnjen). Prosim pull-aj dol nove spremembe iz oddaljenega repozitorija, jih vključi v svoj branch, nato pa poizkusi ponovno. To lahko narediš z `git pull` ali `git pull --rebase`', + 'pl' : 'Zdalne repozytorium różni się od lokalnego repozytorium, dlatego twoich zmian nie można przesłać za pomocą prostego szybkiego `fast forward` (i dlatego polecenie `push` zostało odrzucone). Najpierw zrób `pull` aby pobrać nowe zmiany do lokalnego repozytorium, zintegruj je z branch-em i spróbuj ponownie. Możesz to zrobić za pomocą `git pull` lub `git pull --rebase`' }, 'git-error-remote-branch': { '__desc__': 'One of the error messages for git', @@ -248,12 +328,17 @@ exports.strings = { 'zh_TW': '你不能在遠端分支上執行這個命令呀。', 'de_DE': 'Du kannst diesen Befehl nicht auf einem Remote Branch ausführen', 'es_AR': 'No podés ejecutar ese comando en una rama remota', + 'es_MX': 'No puedes ejecutar ese comando en una rama remota', 'es_ES': 'No puedes ejecutar ese comando en una rama remota', 'pt_BR': 'Você não pode executar esse comando em um ramo remoto', + 'gl' : 'Non podes executar ese comando nunha rama remota', 'fr_FR': 'Vous ne pouvez exécuter cette commande sur une branche distante', 'ru_RU': 'Вы не можете выполнить эту команду на удаленной ветке', 'uk': 'Ти не можеш виконати цю команду на віддаленій гілці', - 'ko': '당신은 원격 브랜치에서 그 명령어를 실행시킬 수 없다.' + 'ko': '당신은 원격 브랜치에서 그 명령어를 실행시킬 수 없습니다.', + 'vi': 'Bạn không thể thực thi lệnh đó lên nhánh từ xa.', + 'sl_SI': 'Tega ukaza ne moreš narediti na oddaljenem branchu', + 'pl' : 'Nie możesz wykonać tego polecenia w zdalnego branch-u' }, 'git-error-origin-required': { '__desc__': 'One of the error messages for git', @@ -262,12 +347,17 @@ exports.strings = { 'zh_TW': '該命令需要一個 origin', 'de_DE': 'Für diesen Befehl wird origin benötigt', 'es_AR': 'Necesitás un origen para ese comando', + 'es_MX': 'Se necesita un origen para ese comando', 'es_ES': 'Se requiere un origen para ese comando.', 'pt_BR': 'É necessário informar uma origem para esse comando', + 'gl' : 'É necesario informar unha orixe para ese comando', 'fr_FR': 'Une origine est requise pour cette commande', 'ru_RU': 'Origin требуется для этой команды', 'uk': 'Для цієї команди потрібний origin', - 'ko': '그 명령어를 위한 오리진이 필요하다.' + 'ko': '그 명령어를 위한 오리진이 필요합니다.', + 'vi': 'Lệnh đó yêu cầu có origin.', + 'sl_SI': 'Origin je potreben za izvedbo tega ukaza', + 'pl' : 'Dla tego polecenia wymagany jest źródło (origin)' }, 'git-error-origin-exists': { '__desc__': 'One of the error messages for git', @@ -276,12 +366,17 @@ exports.strings = { 'zh_TW': 'origin 遠端已存在。你不能重複創建', 'de_DE': 'origin existiert bereits! Du kannst es nicht nochmal anlegen', 'es_AR': '¡Ya existe el origen! No podés crear uno nuevo', + 'es_MX': '¡Ya existe un origen! No puedes crear uno nuevo', 'es_ES': '¡Ya existe un origen! No puedes crearlo de nuevo.', 'pt_BR': 'A origem já existe! Você não pode criar uma nova', + 'gl' : 'A orixe xa existe! Non podes crear unha nova', 'fr_FR': 'Une origine existe déjà ! Vous ne pouvez pas en créer une nouvelle', 'ru_RU': 'Origin уже существует! Невозможно создать еще один', 'uk': 'Origin вже існує! Неможливо створити ще один', - 'ko': '오리진이 이미 존재합니다! 당신은 새로 만들 수 없습니다.' + 'ko': '오리진이 이미 존재합니다! 당신은 새로 만들 수 없습니다.', + 'vi': 'Nguyên bản (origin) đã tồn tại. Bạn không thể tạo thêm 1 cái mới', + 'sl_SI': 'Origin že obstaja. Ne moreš narediti novega.', + 'pl' : 'origem już istnieje! Nie możesz go ponownie założyć' }, /////////////////////////////////////////////////////////////////////////// 'git-error-branch': { @@ -292,12 +387,17 @@ exports.strings = { 'zh_CN': '你不能删除主分支(master),或者你当前所在的分支,或者其它连分支也不是的东西。', 'zh_TW': '你不能刪除 master branch,或者你當前所在的 branch,或者其它連 branch 都不是的東西。', 'es_AR': 'No podés borrar la rama master, la rama en la que estás, o cosas que no son ramas', + 'es_MX': 'No puedes borrar la rama master, la rama en la que estás, o cosas que no son ramas', 'es_ES': 'No puedes eliminar la rama master, la rama en que estás, o cosas que no son ramas.', 'pt_BR': 'Você não pode apagar o ramo master, nem o ramo em que você está, nem coisas que não sejam ramos', + 'gl' : 'Non podes borrala rama master, nin a rama na que ti estás, nin cousas que non sexan ramas', 'fr_FR': 'Vous ne pouvez supprimer la branche master, la branche sur laquelle vous êtes, ou ce qui n\'est pas une branche', 'ru_RU' : 'Невозможно удалить ветку master, ветку на которой вы сейчас и то что не является веткой', 'uk': 'Неможливо видалити гілку master, гілку на якій ти зараз знаходишся чи штуки які не є гілкою', - 'ko': '당신은 마스터 브랜치, 당신이 현재 사용중인 브랜치, 또는 브랜치가 아닌 것들을 삭제할 수 없습니다.' + 'ko': '당신은 메인 브랜치, 당신이 현재 사용중인 브랜치, 또는 브랜치가 아닌 것들을 삭제할 수 없습니다.', + 'vi': 'Bạn không thể xóa nhánh master, nhánh mà bạn đang tham chiếu tới, hoặc những gì không phải nhánh.', + 'sl_SI': 'Ne moreš izbrisati master brancha, brancha na katerem si trenutno ali stvari, ki niso branchi', + 'pl' : 'Nie możesz usunąć branch-a master, branch-a nad którym aktualnie pracujesz, ani który nie jest branch-em' }, /////////////////////////////////////////////////////////////////////////// 'git-merge-msg': { @@ -307,12 +407,17 @@ exports.strings = { 'zh_CN': '合并 {target} 到 {current}', 'zh_TW': '將 {target} 併入 {current}', 'es_AR': 'Mergear {target} a {current}', + 'es_MX': 'Mergear {target} a {current}', 'es_ES': 'Incorporar {target} en {current}', 'pt_BR': 'Merge de {target} em {current}', + 'gl' : 'Merge de {target} en {current}', 'fr_FR': 'Merge de {target} dans {current}', 'ru_RU': 'Слияние {target} в {current}', 'uk': 'Злиття {target} в {current}', - 'ko': '{target}을 {current}에 병합하세요.' + 'ko': '{target}을 {current}에 병합하세요.', + 'vi': 'Gộp {target} vào {current}.', + 'sl_SI': 'Mergaj {target} v {current}', + 'pl' : 'Łączenie {target} z {current}' }, /////////////////////////////////////////////////////////////////////////// 'git-error-rebase-none': { @@ -322,12 +427,17 @@ exports.strings = { 'zh_CN': '没有可以 rebase 的提交记录!可能是合并提交,或者已经 rebase 过了。', 'zh_TW': '沒有需要 rebase 的 commit!每個都是一個 merge commit 或者修改已經被寫入了', 'es_AR': '¡No hay commits para rebasear! Son todos commits de merge o cambios ya aplicados', + 'es_MX': '¡No hay commits para hacer rebase! Todo es un merge commit o cambios ya aplicados', 'es_ES': '¡No hay commits para hacer rebase! Todo es un merge commit o cambios ya hecho.', 'pt_BR': 'Não há commits para o rebase! São todos commits de merge ou mudanças já aplicadas', - 'fr_FR': 'Aucune commit à rebaser ! Tout est soit un commit de merge, soit des modifications déjà appliquées', + 'gl' : '¡Non hai commits para o rebase! Son todos commits de merge ou cambios xa aplicados', + 'fr_FR': 'Aucun commit à rebaser ! C\'est soit un commit de merge, soit des modifications déjà appliquées', 'ru_RU': 'Нет коммитов для rebase! Все в коммите слияния или изменения уже применены', 'uk': 'Нема комітів для rebase! Все в коміті злиття (merge commit) чи зміни вже застосовані', - 'ko': 'rebase를 하기 위한 커밋이 없습니다! 모든 커밋과 변경 사항들의 병합은 이미 적용되었습니다.' + 'ko': 'rebase를 하기 위한 커밋이 없습니다! 모든 커밋과 변경 사항들의 병합은 이미 적용되었습니다.', + 'vi': 'Không có commit nào để rebase. Mọi thứ là merge commit hoặc thay đổi đã được áp dụng.', + 'sl_SI': 'Ni commitov za rebase! Vse je merge commit ali pa so spremembe že dodane', + 'pl' : 'Nie znaleziono commit-u do zmiany! Wszystkie commit-y oraz scalenia lub zmiany już są zastosowane' }, /////////////////////////////////////////////////////////////////////////// 'git-result-nothing': { @@ -337,12 +447,17 @@ exports.strings = { 'zh_CN': '什么也没发生...', 'zh_TW': '沒什麼事情要做...', 'es_AR': 'Nada para hacer...', + 'es_MX': 'Nada para hacer...', 'es_ES': 'Nada para hacer...', 'pt_BR': 'Nada a ser feito...', + 'gl' : 'Nada para facer...', 'fr_FR': 'Rien à effectuer…', 'ru_RU': 'Нечего выполнять...', 'uk': 'Нічого виконувати...', - 'ko': '할게 없습니다 ...' + 'ko': '할게 없습니다 ...', + 'vi': 'Không có gì để làm ...', + 'sl_SI': 'Ničesar za narediti ...', + 'pl' : 'Nie ma nic do zrobienia...' }, /////////////////////////////////////////////////////////////////////////// 'git-result-fastforward': { @@ -352,12 +467,17 @@ exports.strings = { 'zh_CN': '快速前进...', 'zh_TW': '快速前進...', 'es_AR': 'Fast forwardeando...', + 'es_MX': 'Avanzando rápidamente (Fast forwarding)...', 'es_ES': 'Avanzando rápidamente...', 'pt_BR': 'Fast forward...', + 'gl' : 'Fast forward...', 'fr_FR': 'En avance rapide…', 'ru_RU': 'Выполняю Fast forward...', 'uk': 'Виконую Fast forward', - 'ko': 'Fast forward 중입니다...' + 'ko': 'Fast forward 중입니다...', + 'vi': 'Đang fast forward...', + 'sl_SI': 'Fast forwardiranje', + 'pl' : 'Fast forward...' }, /////////////////////////////////////////////////////////////////////////// 'git-result-uptodate': { @@ -367,12 +487,17 @@ exports.strings = { 'zh_CN': '分支已经是最新啦', 'zh_TW': 'branch 已經是最新啦', 'es_AR': 'Rama actualmente actualizada', + 'es_MX': 'La rama ya se ha actualizado.', 'es_ES': 'La rama ya se ha actualizado.', 'pt_BR': 'Ramo já atualizado', + 'gl' : 'Rama xa actualizada', 'fr_FR': 'Branche déjà à jour', 'ru_RU': 'Ветка уже обновлена', 'uk': 'Гілку вже оновлено', - 'ko': '브랜치가 이미 최신 상태입니다.' + 'ko': '브랜치가 이미 최신 상태입니다.', + 'vi': 'Nhánh đã được cập nhật mới nhất.', + 'sl_SI': 'Branch je že posodobljen', + 'pl' : 'Branch jest już aktualny' }, /////////////////////////////////////////////////////////////////////////// 'git-error-exist': { @@ -382,12 +507,17 @@ exports.strings = { 'zh_CN': '引用 {ref} 不存在。', 'zh_TW': '索引 {ref} 不存在,或者找不到。', 'es_AR': 'La referencia {ref} no existe o es desconocida', + 'es_MX': 'La referencia {ref} no existe o es desconocida', 'es_ES': 'La referencia {ref} no existe o es desconocida', 'pt_BR': 'A referência {ref} não existe ou é desconhecida', + 'gl' : 'A referencia {ref} non existe ou é descoñecida', 'fr_FR': 'La référence {ref} n\'existe pas ou est inconnue', 'ru_RU': 'Ссылка {ref} не существует или неизвестна', 'uk': 'Посилання {ref} не існує чи невідоме', - 'ko': '{ref} 참조가 존재하지 않거나 알 수 없습니다.' + 'ko': '{ref} 참조가 존재하지 않거나 알 수 없습니다.', + 'vi': 'Tham chiếu {ref} không tồn tại hoặc không thể tìm thấy.', + 'sl_SI': 'Ref {ref} new obstaja ali je neznan', + 'pl' : 'Odnośnik {ref} nie istnieje lub jest nieznany' }, /////////////////////////////////////////////////////////////////////////// 'git-error-relative-ref': { @@ -397,12 +527,17 @@ exports.strings = { 'zh_CN': '{commit} 提交并没有 {match}', 'zh_TW': 'commit {commit} 並沒有 {match}', 'es_AR': 'El commit {commit} no tiene un {match}', + 'es_MX': 'El commit {commit} no tiene un {match}', 'es_ES': 'El commit {commit} no tiene un {match}', 'pt_BR': 'O commit {commit} não tem um {match}', + 'gl' : 'O commit {commit} non ten un {match}', 'fr_FR': 'Le commit {commit} n\'a pas de correspondance {match}', 'ru_RU': 'Коммит {commit} не содержит {match}', 'uk': 'Коміт {commit} не містить {match}', - 'ko': '커밋 {commit}은 {match}를 가지고 있지 않습니다.' + 'ko': '커밋 {commit}은 {match}를 가지고 있지 않습니다.', + 'vi': 'Commit {commit} mà không có {match}.', + 'sl_SI': 'Commit {commit} nima {match}', + 'pl' : 'Commit {commit} nie ma {match}' }, /////////////////////////////////////////////////////////////////////////// 'git-warning-detached': { @@ -412,12 +547,17 @@ exports.strings = { 'zh_CN': '警告!现在是分离 HEAD 状态', 'zh_TW': '注意喔!現在的狀態是分離 Head', 'es_AR': '¡Cuidado! Modo de detached HEAD', + 'es_MX': '¡Cuidado! Modo de HEAD separado (detached HEAD)', 'es_ES': '¡Cuidado! Modo de HEAD separado (detached HEAD)', 'pt_BR': 'Cuidado! Modo Detached HEAD', + 'gl' : '¡Coidado! Modo Detached HEAD', 'fr_FR': 'Attention ! HEAD est détaché', 'ru_RU': 'Внимание! Репозиторий в состоянии detached HEAD, то есть не находится ни на какой ветке!', 'uk': 'Увага! Репозиторій в стані detached HEAD, тобто не знаходиться в жодній гілці!', - 'ko': '주의! 분리된 HEAD 상태' + 'ko': '주의! 분리된 HEAD 상태', + 'vi': 'Cảnh báo! HEAD bị tách rời', + 'sl_SI': 'Opozorilo! Detached HEAD stanje', + 'pl' : 'Ostrzeżenie!! Odłączony tryb HEAD' }, /////////////////////////////////////////////////////////////////////////// 'git-warning-add': { @@ -427,12 +567,17 @@ exports.strings = { 'zh_CN': '此程序中不需要添加文件', 'zh_TW': '此 demo 中不需要再加入檔案', 'es_AR': 'No es necesario hacer add a los archivos en esta demo', + 'es_MX': 'No es necesario agregar los archivos en ésta demo', 'es_ES': 'No es necesario agregar los archivos en esta demo', 'pt_BR': 'Não é necessário adicionar arquivos neste demo', + 'gl' : 'Non é necesario incluír arquivos nesta demo', 'fr_FR': 'Aucun besoin d\'ajouter des fichiers dans cette démo', 'ru_RU': 'Это демо не оперирует файлами', 'uk': 'Не потрібно додавати файли для цього демо', - 'ko': '이 데모에서는 파일을 추가할 필요가 없습니다.' + 'ko': '이 데모에서는 파일을 추가할 필요가 없습니다.', + 'vi': 'Không cần thêm tập tin trong bản giới thiệu này.', + 'sl_SI': 'Ni potrebe po dodajanju datotetk v tem demotu', + 'pl' : 'Nie ma potrzeby dodawania plików w tym demo' }, /////////////////////////////////////////////////////////////////////////// 'git-error-options': { @@ -443,26 +588,36 @@ exports.strings = { 'zh_TW': '您指定了不相容或錯誤的選項', 'es_ES': 'Las opciones que especificaste son incompatibles o incorrectas.', 'es_AR': 'No es necesario hacer add a los archivos en esta demo', + 'es_MX': 'No es necesario hacer add a los archivos en ésta demo', 'pt_BR': 'As opções que você especificou são incompatíveis ou incorretas', + 'gl' : 'As opcións que especificaches son incompatibles ou incorrectas', 'fr_FR': 'Les options que vous avez spécifiées sont incompatibles ou incorrectes', 'ru_RU': 'Неправильные опции', 'uk': 'Опції, які ти ввів, або некорректні або не підтримуються', - 'ko': '당신이 지정한 그 옵션들은 호환되지 않거나 올바르지 않습니다.' + 'ko': '당신이 지정한 그 옵션들은 호환되지 않거나 올바르지 않습니다.', + 'vi': 'Các tham số bạn chỉ định không tương thích hoặc không chính xác.', + 'sl_SI': 'Opcije, ki si jih podal, so nezdružljive ali napačne', + 'pl' : 'Podane przez Ciebie opcje są niezgodne lub nieprawidłowe' }, /////////////////////////////////////////////////////////////////////////// 'git-error-already-exists': { '__desc__': 'One of the error messages for git', 'en_US': 'The commit {commit} already exists in your changes set, aborting!', - 'de_DE': 'Der Commit {commit} existiert bereit, Abbruch!', + 'de_DE': 'Der Commit {commit} existiert bereits, Abbruch!', 'zh_CN': '{commit} 提交已经存在于你的改动集里,已忽略!', 'zh_TW': 'commit {commit} 已經在你的修改的集合裡,正在停止!', 'es_AR': 'El commit {commit} ya existe en tus cambios, ¡abortando!', + 'es_MX': 'El commit {commit} ya existe en tus cambios, ¡abortando!', 'es_ES': 'El commit {commit} ya existe en tus cambios, ¡abortando!', 'pt_BR': 'O commit {commit} já existe nas suas mudanças, abortando!', + 'gl' : 'O commit {commit} xa existe nos seus cambios, ¡abortando!', 'fr_FR': 'Le commit {commit} existe déjà dans votre ensemble de modifications, opération avortée !', 'ru_RU': 'Коммит {commit} существует, отменяю!', 'uk': 'Коміт {commit} вже існує в твоєму change set, відміна!', - 'ko': '커밋 {commit}은 이미 당신의 변경 내역에 존재합니다. 중단!' + 'ko': '커밋 {commit}은 이미 당신의 변경 내역에 존재합니다. 중단!', + 'vi': 'Commit {commit} đã tồn tại trong những thay đổi của bạn. Đang hủy!', + 'sl_SI': 'Commit {commit} že obstaja v tvoji množici sprememb, prekinjam!', + 'pl' : 'Commit {commit} już istnieje w Twoim zbiorze zmian, przerywam!' }, /////////////////////////////////////////////////////////////////////////// 'git-error-reset-detached': { @@ -472,12 +627,17 @@ exports.strings = { 'zh_CN': '不能在分离的 HEAD 里重置!用 checkout 吧', 'zh_TW': '不能在分離 HEAD 的狀態中重來!用 checkout 來移動吧', 'es_AR': 'No podés hacer reset en el modo detached. Usá checkout si querés moverte', + 'es_MX': 'No puedes hacer reset en el modo separado. Usa checkout si quieres moverte', 'es_ES': 'No puedes hacer reset en el modo separado. Usa checkout si quieres moverte.', 'pt_BR': 'Não se pode fazer reset no modo detached. Use checkout se quiser se mover', - 'fr_FR': 'On ne peut pas effectuer un reset quand head est détaché. Utilisez checkout pour déplacer', + 'gl' : 'Non se pode facer reset no modo detached. Use checkout se te queres mover', + 'fr_FR': 'On ne peut pas effectuer un reset quand HEAD est détaché. Utilisez checkout pour déplacer', 'ru_RU': 'Это невозможно в режиме detached HEAD! Используйте checkout!', 'uk': 'Неможливо зробити reset в стані detached head! Використовуй checkout якщо хочеш змінити розташування', - 'ko': '분리된 HEAD에서 reset할 수 없습니다. 만약 이동시키기를 원한다면 checkout을 사용하세요.' + 'ko': '분리된 HEAD에서 reset할 수 없습니다. 만약 이동시키기를 원한다면 checkout을 사용하세요.', + 'vi': 'Trong trạng thái tách rời `HEAD` thì không thể `reset`. Dùng `checkout` nếu bạn muốn di chuyển.', + 'sl_SI': 'Ni možno resetat, zaradi detached HEADa', + 'pl' : 'Nie można zresetować w odłączonej HEAD! Użyj opcji `checkout`, jeśli chcesz się przenieść' }, /////////////////////////////////////////////////////////////////////////// 'git-warning-hard': { @@ -489,15 +649,23 @@ exports.strings = { 'zh_CN': '在本程序中默认的行为是 --hard 硬重置,可以尽情省略掉那个选项以避免麻烦!但是要记录 Git 中默认的是 --mixed。', 'zh_TW': '預設的行為是 --hard reset,儘量省略掉那個選項吧!', 'es_AR': 'El comportamiento default es un --hard reset, sentite libre de omitir esa opción!', + 'es_MX': 'El comportamiento default es un --hard reset, siéntete libre de omitir esa opción!', 'es_ES': 'El comportamiento default para reajustes es --hard, pero siéntete libre de omitir esa ' + 'opción si te cansas de escribirla en nuestras lecciones. Recuerda quepor defecto el comportamiento en GitHub es --mixed.', 'pt_BR': 'O comportamento padrão é um reset --hard, fique livre para omitir essa opção!', + 'gl' : 'O comportamente por defecto é un reset --hard, Lembra que por defecto en GitHub é --mixed.', 'fr_FR': 'Le comportement par défaut est un --hard reset, soyez libre d\'omettre cette option !', 'ru_RU': 'По умолчанию будет выполнен --hard reset, эту опцию можно опускать!', 'uk': 'На LearnGitBranching reset по замовчуванню використовує --hard, тому цю опцію ' + 'можна пропустити, якщо ти втомився її набирати щоразу. Тільки запам’ятай, що по замовчуванню ' + 'звичайний git reset використовує --mixed', - 'ko': 'LearnGitBranching에서 reset의 기본 설정은 옵션은 --hard입니다. 우리 레슨에서는 이 옵션을 생략해도 됩니다. 다만 실제 Git의 기본 설정 옵션은 --mixed라는것만 기억하세요.' + 'ko': 'LearnGitBranching에서 reset의 기본 설정은 옵션은 --hard입니다. 우리 레슨에서는 이 옵션을 생략해도 됩니다. 다만 실제 Git의 기본 설정 옵션은 --mixed라는것만 기억하세요.', + 'vi': 'Trạng thái mặc định cho lệnh `reset` của \"Học nhánh Git\" là `--hard`.' + + ' Nên khi làm bài nếu bạn thấy gõ tham số này hơi tốn công thì cứ bỏ qua.' + + ' Nhưng mà hãy nhớ rằng thực tế thì `--mixed` mới là trạng thái mặc định của `reset`.', + 'sl_SI': 'Privzeto delovanje za reset na LearnGitBranching je --hard, zato lahko to izpustiš. Na pravem gitu je --mixed.', + 'pl' : 'Domyślnym zachowaniem dla polecenia `reset` w LearnGitBranching jest parametr --hard, więc możesz pominąć tę opcję, ' + + 'Pamiętaj tylko, że domyślne zachowanie rzeczywistego GIT-a jest parametr --mixed.' }, /////////////////////////////////////////////////////////////////////////// 'git-error-staging': { @@ -508,12 +676,17 @@ exports.strings = { 'zh_CN': '没有添加、缓存文件的必要,所以该选项或者命令是不合法的。', 'zh_TW': '沒有加入、或者暫存 (staging) 文件的必要,所以改選項或者命令是不合法的。', 'es_AR': 'No existe el concepto de agregar/indexar cambios, así que esa opción o comando es inválido', + 'es_MX': 'No existe el concepto de agregar/indexar cambios, así que esa opción o comando es inválido', 'es_ES': 'No existe el concepto de agregar/indexar cambios, así que esa opción o comando es inválido.', 'pt_BR': 'Não existe o conceito de adicionar/indexar mudanças, de forma que essa opção ou comando é inválida', + 'gl' : 'Non existe o concepto de agregar/indexar cambios, así que esa opción ou comando é inválido.', 'fr_FR': 'Il n\'y a pas le concept d\'ajouter / mettre en staging, donc cette option ou commande est invalide', 'ru_RU': 'Это демо не работает с файлами, так что git add не нужен!', 'uk': 'В цьому демо немає можливості додати файл до робочої копії чи до стейджингу, тому ця опція чи команда некоректна чи не підтримується', - 'ko': '여기엔 파일을 추가하거나 스테이징한다는 개념이 없습니다. 따라서 그 옵션 또는 명령어는 유효하지 않습니다.' + 'ko': '여기엔 파일을 추가하거나 스테이징한다는 개념이 없습니다. 따라서 그 옵션 또는 명령어는 유효하지 않습니다.', + 'vi': 'Không có khái nệm thêm tập tin đệm(staging file), nên tùy chọn đó là bất hợp lệ.', + 'sl_SI': 'Tu ni možnosti addanja/stageanja datotek, zato je ta ukaz nepravilen', + 'pl' : 'Nie ma koncepcji na dodawanie/indeksowanie zmian, więc opcja lub polecenie jest niepoprawne.' }, /////////////////////////////////////////////////////////////////////////// 'git-revert-msg': { @@ -523,12 +696,17 @@ exports.strings = { 'zh_CN': '撤销 {oldCommit}:{oldMsg}', 'zh_TW': '還原 {oldCommit}:{oldMsg}', 'es_AR': 'Revirtiendo {oldCommit}: {oldMsg}', + 'es_MX': 'Revirtiendo {oldCommit}: {oldMsg}', 'es_ES': 'Volviendo a {oldCommit}: {oldMsg}', 'pt_BR': 'Revertendo {oldCommit}: {oldMsg}', + 'gl' : 'Revertindo {oldCommit}: {oldMsg}', 'fr_FR': 'Revert {oldCommit}: {oldMsg}', 'ru_RU': 'Откатываю {oldCommit}: {oldMsg}', 'uk': 'Повертаю {oldCommit}: {oldMsg}', - 'ko': '{oldCommit}:{oldMsg}를 복구중입니다.' + 'ko': '{oldCommit}:{oldMsg}를 복구중입니다.', + 'vi': 'Hoàn tác {oldCommit}:{oldMsg}.', + 'sl_SI': 'Revertanje {oldCommit}: {oldMsg}', + 'pl' : 'Cofam {oldCommit} : {oldMsg}' }, /////////////////////////////////////////////////////////////////////////// 'git-error-args-many': { @@ -538,12 +716,17 @@ exports.strings = { 'zh_CN': '{what} 期望最多 {upper} 个参数', 'zh_TW': '{what} 期望最多 {upper} 個參數', 'es_AR': 'Espero como máximo {upper} parámetros para {what}', + 'es_MX': 'Espero como máximo {upper} parámetros para {what}', 'es_ES': 'Espero al máximo {upper} parámetros para {what}.', 'pt_BR': 'Espero no máximo {upper} parâmetros para {what}', + 'gl' : 'Espero ó máximo {upper} parámetros para {what}', 'fr_FR': 'J\'attends au plus {upper} argument(s) pour {what}', 'ru_RU': 'Ожидается максимум {upper} аргумент(ов) для {what}', 'uk': 'Я очікую максимум {upper} аргумент(ів) для {what}', - 'ko': '{what}을 위해 최대 {upper}개의 인자를 받습니다.' + 'ko': '{what}을 위해 최대 {upper}개의 인자를 받습니다.', + 'vi': 'Có thể có nhiều nhất {upper} tham số cho {what}.', + 'sl_SI': 'Pričakovanih je največ {upper} argumentov za {what}', + 'pl' : 'Oczekuję maksymalne {upper} parametrów dla {what}' }, /////////////////////////////////////////////////////////////////////////// 'git-error-args-few': { @@ -553,12 +736,17 @@ exports.strings = { 'zh_CN': '{what} 期望最少 {lower} 个参数', 'zh_TW': '{what} 期望最少 {lower} 個參數', 'es_AR': 'Espero al menos {lower} parámetros para {what}', + 'es_MX': 'Espero al menos {lower} parámetros para {what}', 'es_ES': 'Espero al menos {lower} parámetros para {what}.', 'pt_BR': 'Espero pelo menos {lower} parâmetros para {what}', - 'fr_FR': 'J\'attends au moins {upper} argument(s) pour {what}', + 'gl' : 'Agardo polo menos {lower} parámetros para {what}', + 'fr_FR': 'J\'attends au moins {lower} argument(s) pour {what}', 'ru_RU': 'Ожидается как минимум {lower} аргументов для {what}', 'uk': 'Я очікую як мінімум {lower} аргумент(ів) для {what}', - 'ko': '{what}을 위해 최소 {lower}개의 인자를 받습니다.' + 'ko': '{what}을 위해 최소 {lower}개의 인자를 받습니다.', + 'vi': 'Cần ít nhất {lower} tham số cho {what}.', + 'sl_SI': 'Pričakovanih je najmanj {lower} argumentov za {what}', + 'pl' : 'Oczekuję co najmniej {lower} parametrów dla {what}' }, /////////////////////////////////////////////////////////////////////////// 'git-error-no-general-args': { @@ -568,12 +756,17 @@ exports.strings = { 'zh_CN': '该命令不接收参数', 'zh_TW': '該指令不接受一般參數', 'es_AR': 'Ese comando no acepta parámetros comunes', + 'es_MX': 'Ese comando no acepta parámetros comunes', 'es_ES': 'Ese comando no acepta parámetros generales.', 'pt_BR': 'Este comando não aceita parâmetros gerais', + 'gl' : 'Este comando non acepta parámetros xeráis', 'fr_FR': 'Cette commande n\'accepte aucun argument général', 'ru_RU': 'Это команда без аргументов', 'uk': 'Ця команда не приймає загальних аргументів', - 'ko': '그 명령어는 일반적으로 인자를 받지 않습니다.' + 'ko': '그 명령어는 일반적으로 인자를 받지 않습니다.', + 'vi': 'Lệnh đó không chấp nhận các tham số chung.', + 'sl_SI': 'Ta ukaz ne sprejme splošnih ukazov', + 'pl' : 'To polecenie nie przyjmuje żadnych ogólnych parametrów' }, /////////////////////////////////////////////////////////////////////////// 'copy-tree-string': { @@ -583,28 +776,38 @@ exports.strings = { 'zh_CN': '拷贝下面的树字符串', 'zh_TW': '複製下方的樹狀字串', 'es_AR': 'Copiá el código de acá abajo', + 'es_MX': 'Copia el código que se encuentra debajo', 'es_ES': 'Copia el código que sigue.', 'pt_BR': 'Copie o código abaixo', + 'gl' : 'Copie o código abaixo', 'fr_FR': 'Copiez la chaîne d\'arbre ci-dessous', 'ru_RU': 'Скопируй текст ниже', 'uk': 'Скопіюй рядок дерева нижче', - 'ko': '다음 트리 문자열을 복사하세요.' + 'ko': '다음 트리 문자열을 복사하세요.', + 'vi': 'Sao chép chuỗi cây bên dưới.', + 'sl_SI': 'Skopiraj besedilo drevesa spodaj', + 'pl' : 'Skopiuj poniższy kod' }, /////////////////////////////////////////////////////////////////////////// 'learn-git-branching': { '__desc__': 'The title of the app, with spaces', 'en_US': 'Learn Git Branching', - 'de_DE': 'Learn Git Branching', + 'de_DE': 'Lerne Git Branching', 'ja': '日本語版リポジトリ', 'zh_CN': '学习 Git 分支', 'zh_TW': '學習 git 分支', 'es_AR': 'Aprendé a Branchear en Git', + 'es_MX': 'Aprende Git Branching', 'es_ES': 'Aprende Git Branching', 'pt_BR': 'Learn Git Branching', + 'gl' : 'Aprende Git Branching', 'fr_FR': 'Apprenez Git Branching', 'ru_RU': 'Изучаем ветвление в git', - 'uk': 'Learn Git Branching', - 'ko': '깃 브랜칭을 배워봅시다.' + 'uk': 'Вивчай Git Branching', + 'ko': '깃 브랜칭을 배워봅시다.', + 'vi': 'Học nhánh Git.', + 'sl_SI': 'Nauči se Git Branching', + 'pl': 'Nauka GIT Branching-u' }, /////////////////////////////////////////////////////////////////////////// 'select-a-level': { @@ -614,12 +817,17 @@ exports.strings = { 'zh_CN': '选择一关', 'zh_TW': '選擇其中一關', 'es_AR': 'Seleccioná un nivel', + 'es_MX': 'Selecciona un nivel', 'es_ES': 'Selecciona un nivel', 'pt_BR': 'Selecione um nível', + 'gl' : 'Selecciona un nivel', 'fr_FR': 'Choisissez un niveau', 'ru_RU': 'Выбери уровень', 'uk': 'Обери рівень', - 'ko': '레벨을 선택하세요.' + 'ko': '레벨을 선택하세요.', + 'vi': 'Chọn một cấp độ.', + 'sl_SI': 'Izberi stopnjo', + 'pl': 'Wybierz poziom' }, /////////////////////////////////////////////////////////////////////////// 'main-levels-tab': { @@ -629,9 +837,13 @@ exports.strings = { 'zh_CN': '主要', 'zh_TW': '主要', 'es_ES': 'Principal', + 'gl' : 'Principal', 'ru_RU': 'Основы', 'uk' : 'Основи', - 'ko': '메인' + 'ko': '메인', + 'vi': 'Bài học chính', + 'sl_SI': 'Glavno', + 'pl': 'Główny' }, /////////////////////////////////////////////////////////////////////////// 'remote-levels-tab': { @@ -641,9 +853,13 @@ exports.strings = { 'zh_CN': '远程', 'zh_TW': '遠端', 'es_ES': 'Remota', + 'gl' : 'Remota', 'ru_RU': 'Удаленные репозитории', 'uk' : 'Віддалені репозиторії', - 'ko' : '원격' + 'ko' : '원격', + 'vi' : 'Bài học về thao tác từ xa', + 'sl_SI': 'Oddaljeno', + 'pl' : 'Zdalny' }, /////////////////////////////////////////////////////////////////////////// 'branch-name-short': { @@ -653,12 +869,17 @@ exports.strings = { 'zh_CN': '抱歉,为了显示的需要,我们需要一个短些的分支名称。您使用的名称将被截断到9个字符,即 "{branch}"', 'zh_TW': '抱歉,為了顯示的需要,我們需要一個短一點的 branch 名稱。您使用的將會被截斷到剩下9個字元,即"{branch}"', 'es_AR': 'Perdón, necesitamos mantener los nombres de los branches cortos para visualizarlos. El nombre de tu rama se truncó a 9 caracteres, resultando en "{branch}"', - 'es_ES': 'Perdón, necesitamos mantener los nombres de los branches cortos para visualizarlos. El nombre de tu rama se truncó a 9 caracteres, resultando en "{branch}"', + 'es_MX': 'Perdón, necesitamos mantener los nombres de las ramas cortos para visualizarlos. El nombre de tu rama se truncó a 9 caracteres, resultando en "{branch}"', + 'es_ES': 'Perdón, necesitamos mantener los nombres de las ramas cortos para visualizarlos. El nombre de tu rama se truncó a 9 caracteres, resultando en "{branch}"', 'pt_BR': 'Desculpe, precisamos manter os nomes dos ramos curtos para visualizá-los. O nome do seu ramo foi truncado para 9 caracteres, resultando em "{branch}"', + 'gl' : 'Desculpe, precisamos manter os nomes das ramas curtas para poder velas. O nome da súa rama foi truncada a 9 letras, resultado en "{branch}"', 'fr_FR': 'Désolé, nous devons garder les noms de branches courts pour la visualisation. Votre nom de branche a été tronqué à 9 caractères, devenant "{branch}"', 'ru_RU': 'Для наглядности нам нужно сохранять имена веток короткими. Твоё название сокращено до 9 символов и теперь это "{branch}"', 'uk': 'Вибач, нам потрібно щоб ім’я гілок було як можна коротше для наглядності. Твоє ім’я гілки було скорочене до 9 літер й тепер це "{branch}"', - 'ko': '미안하지만, 우리는 시각적으로 더 좋게 보기위해 짧은 브랜치명이 필요합니다. 당신의 브랜치명은 9자리로 잘라 "{branch}"로 만들었습니다.' + 'ko': '미안하지만, 우리는 시각적으로 더 좋게 보기위해 짧은 브랜치명이 필요합니다. 당신의 브랜치명은 9자리로 잘라 "{branch}"로 만들었습니다.', + 'vi': 'Xin lỗi, chúng tôi cần giữ tên nhánh ngắn để tiện minh họa. Tên nhánh của bạn đã bị cắt xuống 9 ký tự là "{branch}".', + 'sl_SI': 'Oprosti, imena branchev moramo obdržati kratka zaradi vizualizacije. Tvoje ime brancha je bilo skrajšano na 9 črk, kar predstavlja "{branch}"', + 'pl': 'Przepraszamy, ze względu na wizualizacje musimy zachować krótkie nazwy branch-y. Nazwa Twojego branch-u została skrócona do 9 znaków, w wyniku czego otrzymano "{branch}"' }, /////////////////////////////////////////////////////////////////////////// 'bad-branch-name': { @@ -668,12 +889,17 @@ exports.strings = { 'zh_CN': '不能给分支起这个名字 "{branch}"', 'zh_TW': '不能给 branch 起這個名字 "{branch}"', 'es_AR': 'El nombre "{branch}" no está permitido para los branches', + 'es_MX': 'El nombre "{branch}" está prohibido para nombrar una rama', 'es_ES': 'El nombre "{branch}" es prohibido para nombrar una rama.', 'pt_BR': 'Um ramo não pode ser chamado de "{branch}"!', + 'gl' : 'Unha rama non pode ser chamada "{branch}', 'fr_FR': 'Ce nom de branche "{branch}" n\'est pas autorisé', 'ru_RU': 'Название для ветки "{branch}" недопустимо!', 'uk': 'Назва гілки "{branch}" є недопустимою', - 'ko': '"{branch}"라는 브랜치명은 사용할 수 없습니다.' + 'ko': '"{branch}"라는 브랜치명은 사용할 수 없습니다.', + 'vi': 'Tên nhánh "{branch}" không được chấp nhận.', + 'sl_SI': 'To ime brancha "{branch}" ni dovoljeno!', + 'pl': 'Ta nazwa oddziału "{branch}" jest niedozwolona!' }, /////////////////////////////////////////////////////////////////////////// 'bad-tag-name': { @@ -682,13 +908,18 @@ exports.strings = { 'zh_CN': '该标签名 “{tag}” 不被接受。', 'zh_TW': '該標籤名 “{tag}” 不被接受。', 'es_AR': 'El nombre "{tag}" no está permitido para los tags', + 'es_MX': 'El nombre "{tag}" está prohibido para nombrar un tag', 'es_ES': 'El nombre "{tag}" es prohibido para nombrar un tag.', 'pt_BR': 'Uma tag não pode ser chamada de "{tag}"!', + 'gl' : 'Unha etiqueta non pode ser chamada "{tag}"', 'de_DE': 'Der Tag-Name "{tag}" ist nicht erlaubt!', - 'fr_FR': 'Le nom de tag "{tag}" n\'est pas autorisé!', + 'fr_FR': 'Le nom de tag "{tag}" n\'est pas autorisé', 'ru_RU': 'Название для тега "{tag}" недопустимо!', 'uk': 'Назва тегу "{tag}" є недопустимою', - 'ko': '"{tag}"라는 태그명은 사용할 수 없습니다.' + 'ko': '"{tag}"라는 태그명은 사용할 수 없습니다.', + 'vi': 'Tên thẻ "{tag}" không được chấp nhận.', + 'sl_SI': 'To ime tag-a "{tag}" ni dovoljeno!', + 'pl': 'Ta nazwa tagu "{tag}" jest niedozwolona!' }, /////////////////////////////////////////////////////////////////////////// 'option-not-supported': { @@ -698,12 +929,17 @@ exports.strings = { 'zh_CN': '不支持选项 "{option}"', 'zh_TW': '不支援的選項 "{option}"', 'es_AR': 'La opción {option} no está soportada', + 'es_MX': 'La opción {option} no es compatible con ésta demo', 'es_ES': 'La opción {option} no compatible con esta demo.', 'pt_BR': 'A opção {option} não é suportada', + 'gl' : 'A opción {option} non está soportada', 'fr_FR': 'L\'option "{option}" n\'est pas supportée', 'ru_RU': 'Опция "{option}" недопустима!', 'uk': 'Опція "{option}" не підтримується!', - 'ko': '"{option}"(이)라는 옵션은 지원하지 않습니다.' + 'ko': '"{option}"(이)라는 옵션은 지원하지 않습니다.', + 'vi': 'Tùy chọn "{option}" không được hỗ trợ.', + 'sl_SI': 'Opcija "{option}" ni podprta! ', + 'pl': 'Opcja "{option}" nie jest obsługiwana!' }, /////////////////////////////////////////////////////////////////////////// 'git-usage-command': { @@ -713,12 +949,17 @@ exports.strings = { 'zh_CN': 'git <命令> [<参数>]', 'zh_TW': 'git <指令> [<參數>]', 'es_AR': 'git []', + 'es_MX': 'git []', 'es_ES': 'git []', - 'pt_BR': 'git ]', + 'pt_BR': 'git []', + 'gl' : 'git []', 'fr_FR': 'git []', 'ru_RU': 'git <команда> [<аргументы>]', 'uk': 'git <команда> [<аргументи>]', - 'ko': 'git <명령어> [<인자들>]' + 'ko': 'git <명령어> [<인자들>]', + 'vi': 'git []', + 'sl_SI': 'git []', + 'pl': 'git []' }, /////////////////////////////////////////////////////////////////////////// 'git-supported-commands': { @@ -728,12 +969,17 @@ exports.strings = { 'zh_CN': '支持的命令有:', 'zh_TW': '支援的指令有:', 'es_AR': 'Comandos soportados:', + 'es_MX': 'Comandos compatibles:', 'es_ES': 'Comandos compatibles:', 'pt_BR': 'Comandos suportados:', + 'gl' : 'Comandos soportados:', 'fr_FR': 'Commandes supportées', 'ru_RU': 'Поддерживаемые команды', 'uk': 'Допустимі команди', - 'ko': '지원되는 명령어들:' + 'ko': '지원되는 명령어들:', + 'vi': 'Các lệnh được hỗ trợ:', + 'sl_SI': 'Podprti ukazi:', + 'pl': 'Obsługiwane polecenia:' }, /////////////////////////////////////////////////////////////////////////// 'git-usage': { @@ -743,12 +989,17 @@ exports.strings = { 'zh_CN': '使用:', 'zh_TW': '用法:', 'es_AR': 'Uso:', + 'es_MX': 'Uso:', 'es_ES': 'Uso:', 'pt_BR': 'Uso:', + 'gl' : 'Uso:', 'fr_FR': 'Utilisation :', 'ru_RU': 'Использование:', 'uk': 'Використання:', - 'ko': '사용법' + 'ko': '사용법', + 'vi': 'Cách dùng:', + 'sl_SI': 'Uporaba:', + 'pl': 'Użyj' }, /////////////////////////////////////////////////////////////////////////// 'git-version': { @@ -758,26 +1009,37 @@ exports.strings = { 'zh_CN': 'Git 版本 PCOTTLE.1.0', 'zh_TW': 'Git 版本 PCOTTLE.1.0', 'es_AR': 'Git Versión PCOTTLE.1.0', + 'es_MX': 'Git Versión PCOTTLE.1.0', 'es_ES': 'Git Versión PCOTTLE.1.0', 'pt_BR': 'Git versão PCOTTLE.1.0', + 'gl' : 'Git versión PCOTTLE.1.0', 'fr_FR': 'Git version PCOTTLE.1.0', 'ru_RU': 'Версия git PCOTTLE.1.0', 'uk': 'Версія git PCOTTLE.1.0', - 'ko': 'Git Version PCOTILE.1.0' + 'ko': 'Git Version PCOTILE.1.0', + 'vi': 'Phiên bản Git TTC-Solutions.1.0', + 'sl_SI': 'Git Verzija PCOTTLE.1.0', + 'pl' : 'Wersja GIT-a OLSZA-1.0' }, /////////////////////////////////////////////////////////////////////////// 'flip-tree-command': { '__desc__': 'when the tree is being flipped', 'en_US': 'Flipping tree...', + 'de_DE': 'Kehre den Baum um...', 'zh_CN': '翻转树中...', 'zh_TW': '翻轉樹中...', 'es_AR': 'Invirtiendo el árbol...', + 'es_MX': 'Invirtiendo el árbol...', 'es_ES': 'Invirtiendo el árbol...', 'pt_BR': 'Invertendo a árvore...', + 'gl' : 'Invirtindo a árbore...', 'fr_FR': 'Inversion de l\'arbre...', 'ru_RU': 'Переворачиваю дерево...', 'uk': 'Перевертаю дерево...', - 'ko': '트리 뒤집는중...' + 'ko': '트리 뒤집는중...', + 'vi': 'Cây lật...', + 'sl_SI': 'Obračanje drevesa ...', + 'pl' : 'Odwracanie drzewa...' }, /////////////////////////////////////////////////////////////////////////// 'refresh-tree-command': { @@ -787,12 +1049,17 @@ exports.strings = { 'zh_CN': '正在刷新树结构...', 'zh_TW': '正在更新樹狀結構...', 'es_AR': 'Refrezcando el árbol...', + 'es_MX': 'Actualizando el árbol...', 'es_ES': 'Actualizando el árbol...', 'pt_BR': 'Atualizando a árvore...', + 'gl' : 'Actualizando a árbore...', 'fr_FR': 'Actualisation de l\'arbre…', 'ru_RU': 'Обновляю дерево...', 'uk': 'Оновлюю дерево...', - 'ko': '트리 다시 불러오는중...' + 'ko': '트리 다시 불러오는중...', + 'vi': 'Làm mới cây...', + 'sl_SI': 'Osveževanje drevesa ...', + 'pl' : 'Odświeżanie drzewa...' }, /////////////////////////////////////////////////////////////////////////// 'locale-command': { @@ -802,12 +1069,17 @@ exports.strings = { 'zh_CN': '语言更改为 {locale}', 'zh_TW': '語系設為 {locale}', 'es_AR': 'Localización actualizada a {locale}', + 'es_MX': 'Idioma actualizado a {locale}', 'es_ES': 'Idioma puesto a {locale}', 'pt_BR': 'Língua trocada para {locale}', + 'gl' : 'Cambiado o idioma a {locale}', 'fr_FR': 'Langue changée à {locale}', 'ru_RU': 'Локаль теперь равна {locale}', 'uk': 'Локаль тепер дорівнює {locale}', - 'ko': '로케일이 {locale}로 설정되었습니다.' + 'ko': '로케일이 {locale}로 설정되었습니다.', + 'vi': 'Ngôn ngữ được thay đổi thành {locale}.', + 'sl_SI': 'Locale nastavljen na {locale}', + 'pl' : 'Ustawiono język na {locale}' }, /////////////////////////////////////////////////////////////////////////// 'locale-reset-command': { @@ -817,12 +1089,17 @@ exports.strings = { 'zh_CN': '语言重置为默认的 {locale}', 'zh_TW': '還原為預設語系 {locale}', 'es_AR': 'Localización vuelta al default, que es {locale}', + 'es_MX': 'Idioma reestablecido al default, que es {locale}', 'es_ES': 'Idioma reajustado a su valor por defecto ({locale})', 'pt_BR': 'Língua retornada para a padrão, que é {locale}', + 'gl' : 'Lingua reaxustada ó seu valor por defecto {locale}', 'fr_FR': 'Langue remise par défaut, qui est {locale}', 'ru_RU': 'Локаль сброшена. Теперь она равна {locale}', 'uk': 'Локаль скинута. Тепер вона дорівнює {locale}', - 'ko': '로케일이 {locale}로 초기화 되었습니다.' + 'ko': '로케일이 {locale}로 초기화 되었습니다.', + 'vi': 'Ngôn ngữ được đổi thành mặc định: {locale}.', + 'sl_SI': 'Locale ponastavljen na {locale}', + 'pl' : 'Przywrócono język do wartości domyślnych, czyli {locale}' }, /////////////////////////////////////////////////////////////////////////// 'show-command': { @@ -832,12 +1109,17 @@ exports.strings = { 'zh_CN': '请使用以下命令以了解更多:', 'de_DE': 'Bitte benutze einen der folgenden Befehle um mehr Informationen zu bekommen:', 'es_AR': 'Usá alguno de estos comandos para tener más información:', + 'es_MX': 'Por favor, utilice alguno de estos comandos para tener más información:', 'es_ES': 'Por favor usa uno de los siguientes comandos para más información:', 'pt_BR': 'Use algum destes comandos para ter mais informações:', - 'fr_FR': 'Merci d\'utiliser une des commandes suivantes pour obtenir plus d\'info', + 'gl' : 'Usa algún destes comandos para ter máis información:', + 'fr_FR': 'Merci d\'utiliser une des commandes suivantes pour obtenir plus d\'informations', 'ru_RU': 'Для получения большей информации используй следующие команды:', 'uk': 'Щоб отримати більше інформації використовуй наступні команди:', - 'ko': '더 많은 정보를 위해 다음 명령어들중 하나를 사용하세요.' + 'ko': '더 많은 정보를 위해 다음 명령어들중 하나를 사용하세요.', + 'vi': 'Vui lòng dùng một trong các lệnh sau để có thêm thông tin:.', + 'sl_SI': 'Prosim uporabi enega od naslednjih ukazov', + 'pl' : 'Aby uzyskać więcej informacji, użyj jednego z następujących poleceń:' }, /////////////////////////////////////////////////////////////////////////// 'show-all-commands': { @@ -845,29 +1127,39 @@ exports.strings = { 'en_US': 'Here is a list of all the commmands available:', 'zh_TW': '這份清單列出所有可用指令:', 'zh_CN': '该列表列出了所有可用的指令:', - 'de_DE': 'Hier ist eine Liste aller verfügbarer Befehle:', + 'de_DE': 'Hier ist eine Liste aller verfügbaren Befehle:', 'es_AR': 'Esta es una lista de los comandos disponibles:', + 'es_MX': 'Esta es una lista de todos los comandos disponibles:', 'es_ES': 'Esta es una lista de todos los comandos disponibles:', 'pt_BR': 'Esta é uma lista dos comandos disponíveis:', + 'gl' : 'Esta é unha lista dos comando dispoñibles:', 'fr_FR': 'Ci-dessous est la liste de toutes les commandes disponibles :', 'ru_RU': 'Вот все поддерживаемуе команды:', 'uk': 'Ось список всіх можливих команд:', - 'ko': '여기에 사용 가능한 모든 명령어들의 리스트가 있습니다.' + 'ko': '여기에 사용 가능한 모든 명령어들의 리스트가 있습니다.', + 'vi': 'Dưới đây là danh sách tất cả các lệnh hiện hành:.', + 'sl_SI': 'Tu je seznam vseh možnih ukazov:', + 'pl' : 'Oto lista wszystkich dostępnych poleceń:' }, /////////////////////////////////////////////////////////////////////////// 'cd-command': { '__desc__': 'dummy command output for the command in the key', 'en_US': 'Directory changed to "/directories/dont/matter/in/this/demo"', - 'de_DE': 'Verzeichnis gewechselt zu "/verzeichnisse/sind/in/dieser/demo/latte"', + 'de_DE': 'Verzeichnis gewechselt zu "/verzeichnisse/sind/in/dieser/demo/irrelevant"', 'zh_CN': '目录切换到 "/directories/dont/matter/in/this/demo"', 'zh_TW': '目錄切換到 "/directories/dont/matter/in/this/demo"', 'es_AR': 'Directorio cambiado a "/los/directorios/no/importan/en/esta/demo"', + 'es_MX': 'Directorio cambiado a "/los/directorios/no/importan/en/esta/demo"', 'es_ES': 'Directorio cambiado a "/los/directorios/no/importan/en/esta/demo"', 'pt_BR': 'Diretório mudado para "/diretorios/nao/importam/neste/demo"', + 'gl' : 'Directorio cambiado a "/os/directorios/non/importan/nesta/demo"', 'fr_FR': 'Répertoire changé à "/directories/dont/matter/in/this/demo" (les répertoires ne servent à rien dans cette démo)', 'ru_RU': 'Директория изменена на "/директории/не/важны/в/этом/демо"', 'uk': 'Директорія змінена на "/директорії/не/мають/значення/в/цьому/демо"', - 'ko': '디렉토리가 "/directories/dont/matter/in/this/demo"로 변경되었습니다.' + 'ko': '디렉토리가 "/directories/dont/matter/in/this/demo"로 변경되었습니다.', + 'vi': 'Thay đổi thư mục thành "/directories/dont/matter/in/this/demo".', + 'sl_SI': 'Mapa spremenjena na "/directories/dont/matter/in/this/demo"', + 'pl' : 'Katalog zmieniony na "/home/users/windows/pl/demo"' }, /////////////////////////////////////////////////////////////////////////// 'ls-command': { @@ -877,26 +1169,36 @@ exports.strings = { 'zh_CN': '在本程序中无须考虑文件问题.txt', 'zh_TW': 'DontWorryAboutFilesInThisDemo.txt (譯註:在 demo 裡不用擔心檔案)', 'es_AR': 'NoTePreocupesPorLosArchivosEnEstaDemo.txt', + 'es_MX': 'NoTePreocupesPorLosArchivosEnEstaDemo.txt', 'es_ES': 'NoTePreocupesPorLosArchivosEnEstaDemo.txt', 'pt_BR': 'NaoSePreocupeComNomesDeArquivoNesteDemo.txt', + 'gl' : 'NonTePreocupesPolosCambiosNestaDemo.txt', 'fr_FR': 'DontWorryAboutFilesInThisDemo.txt (ne vous préoccupez pas des noms de fichier dans cette démo)', 'ru_RU': 'НеНадоЗаботитьсяОФайлахВЭтомДемо.txt', 'uk': 'ЗабийНаФайлиВЦьомуДемо.txt', - 'ko': 'DontWorryAboutFilesInThisDemo.txt (이_데모에서_파일에_대한_걱정은_하지마세요.txt)' + 'ko': 'DontWorryAboutFilesInThisDemo.txt (이_데모에서_파일에_대한_걱정은_하지마세요.txt)', + 'vi': 'DontWorryAboutFilesInThisDemo.txt (ĐừngLoLắngVềTậpTinTrongBảnGiớiThiệuNày.txt)', + 'sl_SI': 'DontWorryAboutFilesInThisDemo.txt', + 'pl' : 'SpokojnieToTylkoPlikDemo.txt' }, 'mobile-alert': { '__desc__': 'When someone comes to the site on a mobile device, they can not input commands so this is a nasty alert to tell them', 'en_US': 'LGB can\'t receive input on mobile, visit on desktop! it\'s worth it :D', - 'de_DE': 'LGB ist nicht mit mobilen Endgeräten kompatibel, nutz es vom Desktop! Es lohnt sich :D', + 'de_DE': 'LGB ist nicht mit mobilen Endgeräten kompatibel, benutz es vom Desktop! Es lohnt sich :D', 'zh_CN': '无法在移动设备/平板上调出键盘 :( 请试试桌面版 :D', 'zh_TW': '無法在行動裝置上叫出鍵盤,請改用桌面版!', 'es_AR': 'LGB no puede recibir comandos en dispositivos móviles. Visitanos desde una desktop, ¡lo vale! :D', + 'es_MX': 'LGB no puede recibir comandos en dispositivos móviles. Visítanos en una computadora de escritorio u laptop, ¡Vale la pena! :D', 'es_ES': 'LGB no puede recibir comandos en dispositivos móviles. Visítanos en una computadora de escritorio, ¡lo vale! :D', 'pt_BR': 'Provavelmente você não vai conseguir digitar comandos no celular, neste caso tente acessar de um computador', + 'gl' : 'LGB non pode recibir os comandos nos dispositivos móbiles. Visítanos dende un ordenador de escritorio, ¡paga a pena! :D', 'fr_FR': 'Impossible de faire apparaître le clavier sur mobile / tablette :( Essayez de passer sur un ordinateur de bureau :D', 'ru_RU': 'Мобильные не поддерживаются, зайди с компьютера!', 'uk': 'LGB не підтримує ввід тексту з мобільного, зайди з компьютера! Це цього варте!', - 'ko': 'LGB는 모바일에서 입력을 받을 수 없습니다. 데스크톱으로 접속하세요! 이것은 가치가 있습니다. :D' + 'ko': 'LGB는 모바일에서 입력을 받을 수 없습니다. 데스크톱으로 접속하세요! 이것은 가치가 있습니다. :D', + 'vi': 'Đáng tiếc là ứng dụng không thể nhận thông tin từ điện thoại hay máy tính bảng, hãy sử dụng máy tính cá nhân, đáng để bỏ công mà :D', + 'sl_SI': 'LGB ne more sprejeti ukazov na mobilni napravi, obiščite nas na računalinku! Je vredno :D ', + 'pl' : 'Przepraszamy, ale LearnGitBranching nie obsługuje wpisywania komend z urządzeń mobilnych. Odwiedź LearnGitBranching na komputerze stacjonarnym, warto! :D' }, /////////////////////////////////////////////////////////////////////////// 'share-tree': { @@ -906,12 +1208,17 @@ exports.strings = { 'zh_CN': '与你的好友分享提交树!他们可以用 "import tree" 加载它', 'zh_TW': '與你的好友分享這棵樹!他們可以用 "import tree" 來載入它', 'es_AR': '¡Compartí este árbol con amigos! Pueden cargarlo con "import tree"', + 'es_MX': '¡Comparte éste árbol con amigos! Pueden cargarlo con "import tree"', 'es_ES': '¡Comparte este árbol con amigos! Pueden cargarlo con "import tree"', 'pt_BR': 'Compartilhe esta árvore com seus amigos! Eles podem carregá-la com "import tree"', + 'gl' : '¡Comparte esta árbore cos teus amigos! Eles poden cargalo con "import tree"', 'fr_FR': 'Partagez cet arbre avec vos amis ! Ils peuvent le charger avec "import tree"', 'ru_RU': 'Поделись деревом с друзьями! Они могут загрузить его при помощи "import tree"', 'uk': 'Поділись цим деревом з друзями! Вони зможуть його завантажити за допомогою "import tree"', - 'ko': '친구들과 이 트리를 공유하세요! 그들은 "import tree"를 사용해 이를 로드할 수 있습니다.' + 'ko': '친구들과 이 트리를 공유하세요! 그들은 "import tree"를 사용해 이를 로드할 수 있습니다.', + 'vi': 'Hãy chia sẻ cây này với bạn của mình! Họ có thể dùng "import tree" để tải.', + 'sl_SI': 'Deli to drevo s prijatelji! Lahko ga naložijo z "import tree"', + 'pl' : 'Udostępnij to drzewo znajomym! Mogą go załadować za pomocą "import tree"' }, /////////////////////////////////////////////////////////////////////////// 'paste-json': { @@ -921,12 +1228,17 @@ exports.strings = { 'zh_CN': '在下边粘贴一个 JSON 串', 'zh_TW': '在下方貼上一串 JSON', 'es_AR': '¡Pegá un blob JSON abajo!', + 'es_MX': '¡Pega un blob JSON abajo!', 'es_ES': '¡Pega un blob JSON abajo!', 'pt_BR': 'Cole o JSON abaixo!', + 'gl' : 'Pega un JSON abaixo!', 'fr_FR': 'Collez un blob JSON ci-dessous !', 'ru_RU': 'Вставь JSON ниже!', 'uk': 'Встав JSON нижче!', - 'ko': '아래에 JSON blob을 붙여넣으세요.' + 'ko': '아래에 JSON blob을 붙여넣으세요.', + 'vi': 'Dán một chuỗi JSON xuống bên dưới.', + 'sl_SI': 'Prilepi JSON kodo spodaj!', + 'pl' : 'Wklej poniżej obiekt z kodem JSON!' }, /////////////////////////////////////////////////////////////////////////// 'solved-map-reset': { @@ -936,42 +1248,57 @@ exports.strings = { 'zh_CN': '解决列表已重置,您现在可以从头开始了', 'zh_TW': '過關地圖已經重新設置,您現在從零開始了', 'es_AR': 'El mapa resuelto fue eliminado, estás arrancando desde un estado limpio', + 'es_MX': 'El mapa resuelto fue eliminado, estás empezando desde un estado limpio', 'es_ES': 'El mapa resuelto fue eliminado, estás empezando de un estado limpio.', 'pt_BR': 'Mapa de resolvidos descartado, você está começando com ficha limpa!', + 'gl' : 'O mapa resolto foi eliminado, estás arrancando dende un estado limpo.', 'fr_FR': 'La carte des niveaux résolus a été effacée, vous repartez de zéro !', 'ru_RU': 'Всё сброшено! Можно начать с чистого листа!', 'uk': 'Все скинуте! Можна починати з чистого аркушу!', - 'ko': '해결된 지도가 초기화 되었습니다. 당신은 깨끗한 상태에서 시작합니다.' + 'ko': '해결된 지도가 초기화 되었습니다. 당신은 깨끗한 상태에서 시작합니다.', + 'vi': 'Tất cả đáp án đã được xóa, bạn có thể bắt đầu lại từ đầu.', + 'sl_SI': 'Rešena mapa je ponastavljena, začel boš lahko na novo!', + 'pl' : 'Rozwiązania zostały wyczyszczone, zaczynasz od czystej karty.' }, /////////////////////////////////////////////////////////////////////////// 'level-cant-exit': { '__desc__': 'When the user tries to exit a level when they are not in one', 'en_US': 'You are not in a level! You are in a sandbox, start a level with "levels"', - 'de_DE': 'Du bist nicht in einem Level! Du bist im Sandkasten-Modus, starte einen Level mit "levels"', + 'de_DE': 'Du bist nicht in einem Level! Du bist im Sandkasten-Modus, starte ein Level mit "levels"', 'zh_CN': '您没在关卡中而是在沙盒中,要开始关卡请输入 "levels"', 'zh_TW': '您沒在關卡中!您在沙盒中,要開始關卡請輸入 "levels"', 'es_AR': '¡No estás en un nivel! Estás en el sandbox, comenzá un nivel usando "levels"', + 'es_MX': '¡No estás en un nivel! Estás en el sandbox, comienza un nivel con "levels"', 'es_ES': '¡No estás en un nivel! Estás en el sandbox, comienza un nivel con "levels"', 'pt_BR': 'Você não está em um nível! Você está no sandbox, comece um nível com "levels"', + 'gl' : '¡Non estás en ningún nivel! Estás nunha caixa de arena, comeza un nivel usando "levels"', 'fr_FR': 'Vous n\'êtes pas dans un niveau ! Vous êtes dans le mode bac à sable, commencez un niveau avec "levels"', 'ru_RU': 'Ты не проходишь уровень! Ты в песочнице! Чтобы начать уровень, используй команду "levels"!', 'uk': 'Ти не в рівні! Ти в пісочниці! Почни рівень з "levels"', - 'ko': '당신은 샌드박스에 있습니다. "levels"를 사용하여 레벨을 시작하세요.' + 'ko': '당신은 샌드박스에 있습니다. "levels"를 사용하여 레벨을 시작하세요.', + 'vi': 'Bạn hiện không ở cấp độ nào cả! Hãy bắt đầu một cấp độ với "levels".', + 'sl_SI': 'Nisi v stopnji! Si v peskovniku, začni stopnjo z "levels"', + 'pl' : 'Nie jesteś na poziomie! Jesteś w piaskownicy, zacznij poziom wpisując "levels"' }, /////////////////////////////////////////////////////////////////////////// 'level-no-id': { - '__desc__': 'When you say an id but that level doesnt exist', + '__desc__': 'When you say an id but that level doesn\'t exist', 'en_US': 'A level for that id "{id}" was not found! Opening up a level selection view', - 'de_DE': 'Konnte keinen Level mit der ID "{id}" finden! Öffne einen Level-Auswahldialog', + 'de_DE': 'Konnte kein Level mit der ID "{id}" finden! Öffne den Level-Auswahldialog', 'zh_CN': '没找到 id 为 "{id}" 的关卡!打开关卡选择框', 'zh_TW': '找不到 id 為 "{id}" 的關卡!開啟關卡選擇視窗', 'es_AR': 'No se encontró ningún nivel {id}. Abriendo la vista de selección de niveles...', + 'es_MX': 'No se encontró ningún nivel {id}. Abriendo la vista de selección de niveles...', 'es_ES': 'No se encontró ningún nivel {id}. Abriendo la vista de selección de niveles...', 'pt_BR': 'O nível "{id}" não existe! Abrindo uma caixa de seleção de nível', + 'gl' : 'O nivel "{id}" non existe! Abrindo unha caixa de seleción de nivel', 'fr_FR': 'Le niveau dont l\'identifiant est {id} n\'a pas été trouvé ! Ouverture de la vue de sélection des niveaux', 'ru_RU': 'Уровень с id "{id}" не найден! Открываю выбор уровней', 'uk': 'Рівень з id "{id}" не знайдений! Відкриваю вибір рівней', - 'ko': 'id "{id}"에 대한 레벨이 존재하지 않습니다. 레벨 선택 화면을 열어보세요.' + 'ko': 'id "{id}"에 대한 레벨이 존재하지 않습니다. 레벨 선택 화면을 열어보세요.', + 'vi': 'Không tìm thấy cấp độ cho định danh "{id}". Mở cửa sổ chọn cấp độ.', + 'sl_SI': 'Stopnja za ta id "{id}" ni bila najdena! Odpiram pogled za izbiro stopnje', + 'pl' : 'Nie znaleziono poziomu {id}!. Otwieranie widoku wyboru poziomu...' }, /////////////////////////////////////////////////////////////////////////// 'undo-stack-empty': { @@ -981,27 +1308,37 @@ exports.strings = { 'zh_CN': '还没有什么可以撤销', 'zh_TW': '還沒有什麼可以取消', 'es_AR': 'No hay comandos que deshacer', + 'es_MX': 'No hay comandos para deshacer', 'es_ES': 'No hay comandos que deshacer', 'pt_BR': 'Você já desfez tudo!', + 'gl' : 'Nonn hai comandos que desfacer', 'fr_FR': 'La pile d\'annulation est vide !', 'ru_RU': 'Некуда откатывать!', - 'uk': 'Нема куди відкатуватися', - 'ko': '되돌리기 스택이 비었습니다!' + 'uk': 'Нема куди відкочуватись!', + 'ko': '되돌리기 스택이 비었습니다!', + 'vi': 'Không có gì để hoàn tác!', + 'sl_SI': 'Undo seznam je prazen!', + 'pl' : 'Nie ma już poleceń do cofnięcia!' }, /////////////////////////////////////////////////////////////////////////// 'already-solved': { '__desc__': 'When you play in a level that is already solved', 'en_US': 'You have already solved this level, try other levels with "levels" or go back to sandbox with "sandbox"', - 'de_DE': 'Du hast diesen Level bereits gelöst, probier einen anderen Level mit "levels" aus oder geh in den Sandkasten-Modus mit "sandbox"', + 'de_DE': 'Du hast dieses Level bereits gelöst, probier ein anderes Level mit "levels" aus oder geh in den Sandkasten-Modus mit "sandbox"', 'zh_CN': '你已经解决了本关,输入 "levels" 尝试其他关卡,或者输入 "sandbox" 回到沙盒中', 'zh_TW': '你已經解决了本關,輸入 "levels" 嘗試其他關卡,或者輸入 "sandbox" 回到沙盒中', 'es_AR': 'Ya resolviste este nivel, probá otros usando "levels" o volvé al sandbox usando "sandbox"', + 'es_MX': 'Ya resolviste este nivel, prueba otros usando "levels" o vuelve al sandbox usando "sandbox"', 'es_ES': 'Ya resolviste este nivel, prueba otros usando "levels" o vuelve al sandbox usando "sandbox"', 'pt_BR': 'Você já resolveu este nível, tente outros com "levels" ou volte ao sandbox com "sandbox"', + 'gl' : 'Xa resolviches este nivel, proba outros usando "levels" ou volve á caixa de area con "sandbox"', 'fr_FR': 'Vous avez déjà résolu ce niveau, essayez d\'autres niveaux avec "levels" ou revenez au bac à sable avec "sandbox"', 'ru_RU': 'Ты уже прошел этот уровень, попробуй пройти другие при помощи команды "levels" или иди в песочницу "sandbox"', 'uk': 'Ти вже пройшов цей рівень, спробуй інші рівні з "levels" чи повернись в пісочницю з "sandbox"', - 'ko': '당신은 이미 이 레벨을 해결했습니다. "levels"를 사용하여 다른 레벨에 도전하거나 "sandbox"를 사용하여 샌드박스로 돌아가세요.' + 'ko': '당신은 이미 이 레벨을 해결했습니다. "levels"를 사용하여 다른 레벨에 도전하거나 "sandbox"를 사용하여 샌드박스로 돌아가세요.', + 'vi': 'Bạn đã vượt qua cấp độ này. Thử cấp độ khác với "levels" hoặc dùng "sandbox" để trở lại hộp cát.', + 'sl_SI': 'To stopnjo si že rešil, poizkusi druge stopnje z "levels" ali pojdi nazaj v peskovnik s "sandbox"', + 'pl' : 'Już rozwiązałeś ten poziom, wypróbuj inne, używając "levels" lub wróć do piaskownicy za pomocą polecenia "sandbox"' }, /////////////////////////////////////////////////////////////////////////// 'solved-level': { @@ -1011,39 +1348,53 @@ exports.strings = { 'zh_CN': '恭喜过关!!', 'zh_TW': '恭喜,本關解決了!!', 'es_ES': '¡Resuelto!\n:D', + 'gl' : '¡Resolto!', 'ru_RU': 'Решено!!\n:D', 'uk' : 'Вирішено!!\n:D', - 'ko' : '해결 완료!!\n:D' + 'ko' : '해결 완료!!\n:D', + 'vi' : 'ĐÃ XONG!!\n:D', + 'sl_SI': 'Rešeno!!\n:D', + 'pl' : 'Rozwiązany!!\n:D' }, /////////////////////////////////////////////////////////////////////////// 'command-disabled': { '__desc__': 'When you try a command that is disabled', 'en_US': 'That git command is disabled for this level!', - 'de_DE': 'Dieser git-Befehl ist für diesen Level deaktiviert!', + 'de_DE': 'Dieser git-Befehl ist für dieses Level deaktiviert!', 'zh_CN': '本关不允许使用该命令!', 'zh_TW': '本關禁止使用該 git 指令!', 'es_AR': '¡Ese comando de git está deshabilitado para este nivel!', + 'es_MX': '¡Ese comando de git está deshabilitado para éste nivel!', 'es_ES': '¡Ese comando de git está deshabilitado para este nivel!', 'pt_BR': 'Achou que seria fácil assim? Desabilitamos esse comando durante este nível, só para dificultar ;-)', + 'gl' : '¡Ese comando de git está deshabilitado para este nivel!', 'fr_FR': 'Cette commande git est désactivée pour ce niveau !', 'ru_RU': 'На этом уровне нельзя использовать эту команду!', 'uk': 'На цьому рівні не можна використовувати цю команду!', - 'ko': '그 Git 명령어는 이 레벨에서 사용할 수 없습니다.' + 'ko': '그 Git 명령어는 이 레벨에서 사용할 수 없습니다.', + 'vi': 'Ở cấp độ này thì lệnh git đó bị vô hiệu hóa.', + 'sl_SI': 'Ta git ukaz je onemogočen za to stopnjo!', + 'pl' : 'To polecenie GIT-a jest wyłączone na tym poziomie!' }, /////////////////////////////////////////////////////////////////////////// 'share-json': { '__desc__': 'when you have made the level, prompt to share this', - 'en_US': 'Here is the JSON for this level! Share it with someone or send it to me on Github', - 'de_DE': 'Hier ist das JSON für diesen Level! Teil es mit jemandem or schick es mir über Github', - 'zh_CN': '这是一个关卡定义 JSON !您可以分享它或者发到我的 Github 上', - 'zh_TW': '這是本關的 JSON!您可以分享給別人,或是送到 Github 上給我', - 'es_AR': 'Este es el JSON de este nivel. Compartilo con quien quieras o mandámelo por Github', - 'es_ES': 'Este es el JSON de este nivel. Compártelo con quien quieras o mandámelo por Github.', - 'pt_BR': 'Aqui está o JSON para este nível! Compartilhe com alguém ou me envie pelo Github', - 'fr_FR': 'Voici le JSON pour ce niveau ! Partagez-le avec quelqu\'un ou envoyez-le moi sur Github', + 'en_US': 'Here is the JSON for this level! Share it with someone or send it to me on GitHub', + 'de_DE': 'Hier ist das JSON für dieses Level! Teil es mit jemandem or schick es mir über GitHub', + 'zh_CN': '这是一个关卡定义 JSON !您可以分享它或者发到我的 GitHub 上', + 'zh_TW': '這是本關的 JSON!您可以分享給別人,或是送到 GitHub 上給我', + 'es_AR': 'Este es el JSON de este nivel. Compartilo con quien quieras o mandámelo por GitHub', + 'es_MX': 'Este es el JSON de éste nivel. Compártelo con quien quieras o mándamelo por GitHub.', + 'es_ES': 'Este es el JSON de este nivel. Compártelo con quien quieras o mandámelo por GitHub.', + 'pt_BR': 'Aqui está o JSON para este nível! Compartilhe com alguém ou me envie pelo GitHub', + 'gl' : 'Este é o JSON deste nivel. Comparteo con quen queiras ou mándao por GitHub', + 'fr_FR': 'Voici le JSON pour ce niveau ! Partagez-le avec quelqu\'un ou envoyez-le moi sur GitHub', 'ru_RU': 'Вот JSON для этого уровня! Поделись им с кем-нибудь или отправь его нам на GitHub', - 'uk': 'Ось JSON для цього рівня! Поділись з кимось чи відправ мені його на Github', - 'ko': '이 레벨을 위한 JSON 데이터가 있습니다! 이를 다른 사람들과 공유하거나 Github에서 제게 보내보세요.' + 'uk': 'Ось JSON для цього рівня! Поділись з кимось чи відправ мені його на GitHub', + 'ko': '이 레벨을 위한 JSON 데이터가 있습니다! 이를 다른 사람들과 공유하거나 GitHub에서 제게 보내보세요.', + 'vi': 'Đây là chuỗi JSON cho cấp độ này! Hãy chia sẻ với người khắc hoặc với tôi qua GitHub.', + 'sl_SI': 'Tu je JSON za to stopnjo! Deli ga z nekom ali ga pošlji meni na GitHub', + 'pl' : 'To jest JSON dla tego poziomu. Udostępnij go, komu chcesz, lub wyślij do mnie na GitHub.' }, /////////////////////////////////////////////////////////////////////////// 'want-start-dialog': { @@ -1053,12 +1404,17 @@ exports.strings = { 'zh_CN': '您还没有定义一开始的介绍,是否添加一个?', 'zh_TW': '尚未指定開始對話視窗,是否立即新增?', 'es_AR': 'No especificaste un mensaje de inicio, ¿querés agregar uno?', + 'es_MX': 'No especificaste un mensaje de inicio, ¿Quieres agregar uno?', 'es_ES': 'No especificaste un mensaje de inicio, ¿quieres agregar uno?', 'pt_BR': 'Você não especificou uma mensagem de início, quer colocar uma?', + 'gl' : 'Non especificaches unha mensaxe de incio. ¿queres agregar un?', 'fr_FR': 'Vous n\'avez pas spécifié de dialogue de départ, voulez-vous en ajouter un ?', 'ru_RU': 'Не указано стартово сообщение! Точно продолжаем?', 'uk': 'Не вказано стартовий діалог, хочеш додати стартовий діалог?', - 'ko': '당신은 시작 대화창을 지정하지 않았습니다. 추가 하시겠습니까?' + 'ko': '당신은 시작 대화창을 지정하지 않았습니다. 추가 하시겠습니까?', + 'vi': 'Không có cửa sổ hội thoại được chỉ định, thêm một cái chứ?', + 'sl_SI': 'Nisi določil začetnega dialoga, bi ga rad dodal?', + 'pl' : 'Nie określiłeś okna startowego, czy chcesz je dodać?' }, /////////////////////////////////////////////////////////////////////////// 'want-hint': { @@ -1068,42 +1424,57 @@ exports.strings = { 'zh_CN': '您还没有定义提示,是否添加一个?', 'zh_TW': '尚未指定提示,是否立即新增?', 'es_AR': 'No especificaste ninguna pista, ¿querés agregar alguna?', + 'es_MX': 'No especificaste ninguna pista, ¿Quieres agregar alguna?', 'es_ES': 'No especificaste ninguna pista, ¿quieres agregar alguna?', 'pt_BR': 'Você não especificou uma dica, quer colocar uma?', + 'gl' : 'Ti non especificaches unha pista, ¿queres agregar algunha?', 'fr_FR': 'Vous n\'avez pas spécifié d\'indice, voulez-vous en ajouter un ?', 'ru_RU': 'Не указана подсказка для уровня! Пренебречь? Вальсируем?', 'uk': 'Не вказана підказка, хочеш додати підказку?', - 'ko': '당신은 힌트를 지정하지 않았습니다. 추가 하시겠습니까?' + 'ko': '당신은 힌트를 지정하지 않았습니다. 추가 하시겠습니까?', + 'vi': 'Bạn chưa chỉ định một gợi ý, thêm một cái chứ?', + 'sl_SI': 'Nisi določil namiga, bi ga rad dodal?', + 'pl' : 'Nie podałeś podpowiedzi, czy chcesz ją dodać?' }, /////////////////////////////////////////////////////////////////////////// 'prompt-hint': { '__desc__': 'prompt for hint', 'en_US': 'Enter the hint for this level, or leave this blank if you do not want to include one', - 'de_DE': 'Gib den Hinweis für diesen Level an, oder lass es leer wenn du keinen hinzufügen willst', + 'de_DE': 'Gib den Hinweis für dieses Level an, oder lass es leer wenn du keinen hinzufügen willst', 'zh_CN': '请输入关卡提示,如果没有请留空', 'zh_TW': '請輸入關卡提示,或者故意留空', 'es_AR': 'Ingresá una pista para este nivel, o dejalo en blanco si no querés incluir ninguna', + 'es_MX': 'Ingresa una pista para este nivel, o déjalo en blanco si no quieres incluir ninguna.', 'es_ES': 'Ingresa una pista para este nivel, o déjalo en blanco si no quieres incluir ninguna.', 'pt_BR': 'Colocque uma dica para este nível, ou deixe em branco se não quiser incluir', + 'gl' : 'Ingresa unha pista para este nivel, ou déixao en branco se non a queres incluír.', 'fr_FR': 'Entrez l\'indice pour ce niveau, ou laissez-le vide pour ne pas l\'inclure', 'ru_RU': 'Введи подсказку для уровня, если хочешь.', 'uk': 'Додай підказку для рівня, якщо хочеш', - 'ko': '이 레벨을 위한 힌트를 입력하거나 만약 이를 포함시키고 싶지 않을 경우엔 비워두세요.' + 'ko': '이 레벨을 위한 힌트를 입력하거나 만약 이를 포함시키고 싶지 않을 경우엔 비워두세요.', + 'vi': 'Thêm một gợi ý cho cấp độ này, hoặc cứ để trống nếu bạn không muốn thêm.', + 'sl_SI': 'Vnesi namig za to stopnjo ali pusti to prazno, če ga nočeš dodati', + 'pl' : 'Wpisz wskazówkę dotyczącą tego poziomu lub pozostaw ją pustą, jeśli nie chcesz jej uwzględniać.' }, /////////////////////////////////////////////////////////////////////////// 'prompt-name': { '__desc__': 'prompt for level name', 'en_US': 'Enter the name for the level', - 'de_DE': 'Gib den Namen für diesen Level an', + 'de_DE': 'Gib den Namen für dieses Level an', 'zh_CN': '请输入关卡名称', 'zh_TW': '請輸入關卡名稱', 'es_AR': 'Ingresá el nombre del nivel', + 'es_MX': 'Ingresa el nombre del nivel', 'es_ES': 'Ingresa el nombre del nivel.', 'pt_BR': 'Coloque o nome do nível', + 'gl' : 'Coloque o nome do nivel', 'fr_FR': 'Entrez le nom pour ce niveau', 'ru_RU': 'Введи название уровня', 'uk': 'Введи назву рівня', - 'ko': '레벨 이름을 입력하세요.' + 'ko': '레벨 이름을 입력하세요.', + 'vi': 'Nhập tên cho cấp độ này.', + 'sl_SI': 'Vnesi ime za stopnjo', + 'pl' : 'Wprowadź nazwę poziomu' }, /////////////////////////////////////////////////////////////////////////// 'solution-empty': { @@ -1113,42 +1484,57 @@ exports.strings = { 'zh_CN': '你的解法是空的!! 可能是程序出错了', 'zh_TW': '您的解法是空的!這一定是哪裡出錯了', 'es_AR': '¡Tu solución está vacía! Algo hay que hacer', + 'es_MX': '¡Tu solución está vacía! Algo hay que hacer', 'es_ES': '¡Tu solución está vacía! Algo hay que hacer.', 'pt_BR': 'Sua solução está vazia! O aprendiz deveria ter que fazer alguma coisa', + 'gl' : '¡Su solución está vacía! Algo haberá que facer.', 'fr_FR': 'Votre solution est vide !! Quelque chose ne tourne pas rond', 'ru_RU': 'Решение не указано! Так не годится!', 'uk': 'Розв’язок порожній!! Щось не так', - 'ko': '해답이 비어있습니다. 무언가 잘못되었습니다.' + 'ko': '해답이 비어있습니다. 무언가 잘못되었습니다.', + 'vi': 'Đáp án bị bỏ trống!! Có gì thiếu rồi.', + 'sl_SI': 'Tvoja rešitev je prazna!! Nekaj ni vredu.', + 'pl' : 'Twoje rozwiązanie jest puste!! Coś musi zostać zrobione.' }, /////////////////////////////////////////////////////////////////////////// 'define-start-warning': { '__desc__': 'When you define the start point again, it overwrites the solution and goal so we add a warning', 'en_US': 'Defining start point... solution and goal will be overwritten if they were defined earlier', - 'de_DE': 'Lege Start fest ... Auflösung und Ziel werden gelößcht, falls sie schon festgelegt worden waren', + 'de_DE': 'Lege Startpunkt fest ... Auflösung und Ziel werden überschrieben, falls sie schon festgelegt waren', 'zh_CN': '定义开始点... 解决方法和目标会被新的替代', 'zh_TW': '正在定義起始點...先前定義的解法和目標會被覆蓋掉', 'es_AR': 'Estableciendo el punto de inicio... La solución y el objetivo serán sobreescritos si ya habían sido definidos', + 'es_MX': 'Estableciendo el punto de inicio... La solución y el objetivo serán sobreescritos si ya habían sido definidos', 'es_ES': 'Estableciendo el punto de inicio... La solución y el objetivo serán sobreescritos si ya habían sido definidos.', 'pt_BR': 'Esbelecendo o ponto de início... a solução e o objetivo serão sobrescritos caso já existirem', + 'gl' : 'Establecendo o punto de inicio... A solución e o obxectivo serán sobreescritos se xa foron definidos.', 'fr_FR': 'Redéfinition du point de départ… la solution et la cible seront écrasés s\'ils ont déjà été définis', 'ru_RU': 'Устанавливаю стартовую точку... Решение и итоговое состояние будут стёрты, если они указаны ранее', 'uk': 'Встановлюю стартову точку... розв’язок та ціль будуть переписані якщо вони були задані раніше', - 'ko': '시작 지점을 정의하세요... 만약 그것이 먼저 정의된다면 해답과 목표가 덮어씌워질 것입니다.' + 'ko': '시작 지점을 정의하세요... 만약 그것이 먼저 정의된다면 해답과 목표가 덮어씌워질 것입니다.', + 'vi': 'Xác định điểm bắt đầu ... Các giải pháp và mục tiêu sẽ được thay thế nếu đã được chỉ định từ trước.', + 'sl_SI': 'Določanje začetne točke ... rešitev in cilj bosta povožena, če sta bila prej že podana', + 'pl' : 'DUstawianie punktu początkowego... Rozwiązanie i cel zostaną nadpisane, jeśli zostały wcześniej zdefiniowane' }, /////////////////////////////////////////////////////////////////////////// 'help-vague-level': { '__desc__': 'When you are in a level and you say help, its vague and you need to specify', 'en_US': 'You are in a level, so multiple forms of help are available. Please select either "help level" to learn more about this lesson, "help general" for using Learn GitBranching, or "objective" to learn about how to solve the level.', - 'de_DE': 'Du befindest dich in einem Level, daher gibt es verschiedene Hilfen. Gib "help level" ein um mehr úber diesen Level zu erfahren, "help general" um zu sehen wie Learn Git Branching bedient wird, oder "objective" um das Ziel dieses Levels zu erfahren.', + 'de_DE': 'Du befindest dich in einem Level, daher gibt es verschiedene Hilfen. Gib "help level" ein um mehr úber dieses Level zu erfahren, "help general" um zu sehen wie Learn Git Branching bedient wird, oder "objective" um das Ziel dieses Levels zu erfahren.', 'zh_CN': '您正在关卡中,这里有多种形式的帮助,请选择 "help level" (关卡帮助)或 "help general" (一般帮助)', 'zh_TW': '您正在進行關卡中,這裡有多種不同型式的幫助,請選擇 "help level" 來了解這個關卡,或者是選擇 "help general" 來學習如何使用 Learn GitBranching,或者是選擇 "objective" 來學習如何解決這個關卡', 'es_AR': 'Estás en un nivel, por lo que hay varios tipos de ayuda. Por favor elegí entre "help level" para aprender algo más sobre esta lección, "help general" para ayuda sobre el uso de Learn GitBranching, o "objective" para aprender a resolver este nivel.', + 'es_MX': 'Estás en un nivel, por lo que hay varios tipos de ayuda. Por favor elige entre "help level" para aprender algo más sobre ésta lección, "help general" para ayuda sobre el uso de Learn GitBranching, o "objective" para aprender a resolver este nivel.', 'es_ES': 'Estás en un nivel, por lo que hay varios tipos de ayuda. Por favor elige "help level" para aprender más sobre esta lección, "help general" para ayuda sobre el uso de Learn GitBranching, o "objective" para aprender a resolver este nivel.', 'pt_BR': 'Você está em um nível, então há vários tipos de ajuda. Selecione "help level" para aprender mais sobre esta lição, "help general" para aprender a usar o Learn GitBranching, ou "objective" ver como resolver o nível.', + 'gl' : 'Estás nun nivel, entón hai varios tipos de axuda. Selecione "help level" para aprender máis sobre esta lección, "gelp general" para aprender a usar o Learn Git Branching, ou "objective" para ver como resolver o nivel.', 'fr_FR': 'Vous êtes dans un niveau, donc plusieurs formes d\'aide sont disponibles. Merci de sélectionner soit "help level" pour en apprendre plus sur cette leçon, "help general" pour l\'utilisation de Learn GitBranching, ou "objective" pour apprendre comment résoudre le niveau', 'ru_RU': 'При прохождении уровня доступны несколько видов помощи. Определить что нужно: "help level" чтобы получить информацию об этом уровне, "help general" для того, чтобы узнать о игре в целом или "objective" чтобы узнать что надо сделать в этом уровне.', 'uk': 'При проходженні рівня доступні декілька різновидів допомоги. Виберіть або "help level" щоб взнати більше про цей рівень, чи "help general" щоб взнати більше про Learn Git Branching, чи "objective" щоб дізнатись більше про проходження цього рівня', - 'ko': '당신은 한 레벨에 들어가 있고, 여러가지 도움 양식들을 사용할 수 있습니다. 레슨에 대해 더 알고싶을 땐 "help level", LearnGitBranching을 사용하고 싶을 땐 "help general", 또는 레벨을 어떻게 해결해야할지 알고싶을 땐 "objective"를 선택하세요.' + 'ko': '당신은 한 레벨에 들어가 있고, 여러가지 도움 양식들을 사용할 수 있습니다. 레슨에 대해 더 알고싶을 땐 "help level", LearnGitBranching을 사용하고 싶을 땐 "help general", 또는 레벨을 어떻게 해결해야할지 알고싶을 땐 "objective"를 선택하세요.', + 'vi': 'Bạn đang ở trong một cấp độ, nên sẽ có nhiều hỗ trợ. Vui lòng dùng "help level" để biết thêm về bài học này, "help general" để sử dụng HọcNhánhGit, hoặc "objective" để biết cách giải quyết bài tập.', + 'sl_SI': 'Si v stopnji, zato so na voljo različne pomoči. Prosim izberi "help level" za več informacij o tej lekciji, "help general" za splošna navodila ali "objective" da izveš kako rešiti to stopnjo', + 'pl' : 'Jesteście na jednym z poziomów, więc istnieje kilka rodzajów pomocy. Wpisz "help level", aby dowiedzieć się więcej o tej lekcji, wpisz "help general", aby uzyskać pomoc dotyczącą korzystania z nauki GitBranching, lub wpisz "objective", aby dowiedzieć się, jak rozwiązać ten poziom.' }, /////////////////////////////////////////////////////////////////////////// 'help-vague-builder': { @@ -1158,44 +1544,59 @@ exports.strings = { 'zh_CN': '您正在进行关卡构建中,这里有多种形式的帮助,请选择 "help general" (一般帮助)或 "help builder" (关卡构建帮助)', 'zh_TW': '您正在進行關卡構建中,這裡有多種不同型式的幫助,請選擇 "help general" (一般幫助)或 "help builder" (製造關卡的幫助)', 'es_AR': 'Estás en el constructor de niveles, por lo que hay varios tipos de ayuda. Elegí entre "help general" para ayuda sobre Learn GitBranching y "help builder" para ayuda sobre el constructor de niveles', + 'es_MX': 'Estás en el constructor de niveles, por lo que hay varios tipos de ayuda. Elige "help general" para ayuda sobre Learn GitBranching y "help builder" para ayuda sobre el constructor de niveles', 'es_ES': 'Estás en un constructor de niveles, por lo que hay varios tipos de ayuda. Elige "help general" para ayuda sobre Learn GitBranching o "help builder" para ayuda sobre el constructor de niveles', 'pt_BR': 'Você está no construtor de nívels, então há vários tipos de ajuda. Selecione "help general" ou "help builder"', + 'gl' : 'Estás no constructor de niveis, polo que hai varios tipos de axuda. Elixe "help general" ou "help builder"', 'fr_FR': 'Vous êtes dans l\'éditeur de niveaux, donc plusieurs formes d\'aide sont disponibles. Merci de sélectionner soit "help general" soit "help builder"', 'ru_RU': 'При создании уровней доступны несколько видов помощи. Выбери между "help general" и "help builder"', 'uk': 'При створенні рівня доступні декілька різновидів допомоги. Виберіть або "help general", чи "help builder"', - 'ko': '당신은 한 레벨 생성기에 들어가 있고, 여러가지 도움 양식들을 사용할 수 있습니다. "help general" 또는 "help builder"를 선택해주세요.' + 'ko': '당신은 한 레벨 생성기에 들어가 있고, 여러가지 도움 양식들을 사용할 수 있습니다. "help general" 또는 "help builder"를 선택해주세요.', + 'vi': 'Bạn đang tạo một cấp độ, nên sẽ có nhiều trợ giúp có sẵn. Vui lòng chọn "help general" hoặc "help builder".', + 'sl_SI': 'Si v graditelju stopenj, zato so na voljo različne pomoči. Prosim izberi "help general" ali "help builder"', + 'pl' : 'Jesteś w kreatorze poziomów, więc dostępnych jest wiele form pomocy. Wpisz "help general", aby uzyskać pomoc dotyczącą nauki GitBranching-u, lub wpisz "help builder", aby uzyskać pomoc dotyczącą konstruktora poziomów' }, /////////////////////////////////////////////////////////////////////////// 'show-goal-button': { '__desc__': 'button label to show goal', 'en_US': 'Show Goal', - 'de_DE': 'Schauen Ziel', + 'de_DE': 'Ziel anzeigen', 'zh_TW': '顯示目標', 'zh_CN': '显示目标', 'fr_FR': 'Afficher les cibles', 'pt_BR': 'Mostrar objetivo', + 'gl' : 'Amosar obxectivo', 'es_AR': 'Mostrar objetivo', + 'es_MX': 'Mostrar objetivo', 'es_ES': 'Mostrar objetivo', 'ja' : 'ゴールを表示', 'ru_RU': 'Цель уровня', 'uk': 'Ціль рівня', - 'ko': '목표 보기' + 'ko': '목표 보기', + 'vi': 'Hiển thị mục tiêu', + 'sl_SI': 'Prikaži Cilj', + 'pl' : 'Pokaż cel' }, /////////////////////////////////////////////////////////////////////////// 'hide-goal-button': { '__desc__': 'button label to hide goal', 'en_US': 'Hide Goal', - 'de_DE': 'Verstecken Ziel', + 'de_DE': 'Ziel verstecken', 'fr_FR': 'Cacher les cibles', 'zh_TW': '隱藏目標', 'zh_CN': '隐藏目标', 'pt_BR': 'Ocultar objetivo', + 'gl' : 'Ocultar obxectivo', 'es_AR': 'Ocultar objetivo', + 'es_MX': 'Ocultar objetivo', 'es_ES': 'Ocultar objetivo', 'ja' : 'ゴールを隠す', 'ru_RU': 'Спрятать цель', 'uk': 'Сховати ціль', - 'ko': '목표 숨기기' + 'ko': '목표 숨기기', + 'vi': 'Ẩn mục tiêu', + 'sl_SI': 'Skrij Cilj', + 'pl' : 'Ukryj cel' }, /////////////////////////////////////////////////////////////////////////// 'objective-button': { @@ -1205,9 +1606,13 @@ exports.strings = { 'zh_TW': '提示', 'zh_CN': '提示', 'es_ES': 'Objetivo', + 'gl' : 'Obxectivo', 'ru_RU': 'Задача', 'uk': 'Задача', - 'ko': '목적' + 'ko': '목적', + 'vi': 'Chỉ dẫn', + 'sl_SI': 'Navodila', + 'pl' : 'Instrukcje' }, /////////////////////////////////////////////////////////////////////////// 'git-demonstration-title': { @@ -1216,26 +1621,35 @@ exports.strings = { 'de_DE': 'Git Demonstration', 'zh_TW': 'Git示範', 'zh_CN': 'Git示范', - 'es_ES': 'Demonstración de Git', + 'es_ES': 'Demostración de Git', + 'gl' : 'Demostración de Git', 'ru_RU': 'Git демо', 'uk' : 'Git демо', - 'ko' : 'Git 데모' + 'ko' : 'Git 데모', + 'vi' : 'Trình diễn Git', + 'sl_SI': 'Git Predstavitev', + 'pl' : 'Demo GIT' }, /////////////////////////////////////////////////////////////////////////// 'goal-to-reach': { '__desc__': 'title of window that shoes the goal tree to reach', 'en_US': 'Goal To Reach', - 'de_DE': 'Ziel', + 'de_DE': 'Zu erreichendes Ziel', 'zh_CN': '目标', 'zh_TW': '目標', 'es_AR': 'Objetivo a cumplir', + 'es_MX': 'Objetivo a cumplir', 'es_ES': 'Objetivo a cumplir', 'pt_BR': 'Objetivo a cumprir', + 'gl' : 'Obxectivo a cumprir', 'fr_FR': 'Cible à atteindre', 'ja' : '到達目標', 'ru_RU': 'Цель уровня', 'uk': 'Ціль рівня', - 'ko': '목표' + 'ko': '목표', + 'vi': 'Mục tiêu cần đạt', + 'sl_SI': 'Končni Cilj', + 'pl': 'Cel do osiągnięcia' }, /////////////////////////////////////////////////////////////////////////// 'goal-only-master': { @@ -1244,14 +1658,19 @@ exports.strings = { 'fr_FR': 'Note: Dans ce niveau on ne doit faire de git checkout que sur la branche master. Les autres branches représentées ici (entourées d\'un cadre en tirets) doivent être utilisées uniquement comme références. Comme toujours, vous pouvez cacher cette fenêtre avec "Cacher les objectifs"', 'de_DE': 'Hinweis: In diesem Level wird nur der Branch master geprüft. Die anderen Branches dienen nur als Vergleichsbasis (als gestrichelte Bezeichner dargestellt). Wie immer kannst du diese Meldung mit "hide goal" ausblenden', 'es_AR': 'Nota: Sólo la rama master va a ser chequeada en este nivel. Las otras ramas sólo son para referencia. Como siempre, podés ocultar este mensaje con "hide goal"', + 'es_MX': 'Nota: Sólo la rama master va a ser inspeccionada en este nivel. Las otras ramas sólo son para referencia (etiquetados abajo con guión). Como siempre, puedes ocultar éste mensaje con "hide goal"', 'es_ES': 'Nota: Sólo la rama master va a ser inspeccionado en este nivel. Las otras ramas sólo son para referencia (etiquetados abajo con guion). Siempre puedes ocultar este mensaje con "hide goal."', 'pt_BR': 'Nota: Apenas o ramo master será verificado neste nível. Os outros ramos (dentro das caixas clareadas) são somente para referência. Como sempre, você pode ocultar esta janela com "hide goal"', + 'gl': 'Nota: Só a rama master será verificada neste nivel. As outras ramas (dentro das caixas clareadas) son soamente de referencia. Coma sempre, podes ocultar está ventá con "hide goal"', 'zh_CN': '注意:本关卡中,只检查 master 分支,其他分支只是用作 reference 存在(以虚线标签表示)。照常,你可以用 “hide goal” 来隐藏此窗口。', 'zh_TW': '在這個關卡中,只有 master branch 會被檢查,別的 branch 只是用來做為 reference (下面用虛線符號表示)。一如往常,你可以利用 "hide goal" 來隱藏這個對話視窗', 'ja': 'Note: masterブランチだけをこのlevelではチェックします。その他のブランチ(以下では、破線で示されています)に関しては、参照のためにあります。また、いつでもこのウィンドウは"hide goal"と打つかクリックで閉じれます', 'ru_RU': 'Важно: В этом уровне проверяется только ветка master. Остальные ветки просто для наглядности. Как обычно, можно скрыть это сообщение при помощи "hide goal"', 'uk': 'Важливо: В цьому рівні буде перевірятися тільки гілка master. Решта гілок тільки для наглядності (показані пунктиром нижче). Як завжди, можна сховати цей діалог за допомогою "hide goal"', - 'ko': 'Note: 이 레벨에선 오직 마스터 브랜치만이 검사될 것입니다.. 다른 브랜치들은 단순히 참고용입니다. (아래에 대시 라벨로 보여집니다.). "hide goal"을 사용하여 언제든지 창을 숨킬 수 있습니다.' + 'ko': 'Note: 이 레벨에선 오직 메인 브랜치만이 검사될 것입니다.. 다른 브랜치들은 단순히 참고용입니다. (아래에 대시 라벨로 보여집니다.). "hide goal"을 사용하여 언제든지 창을 숨길 수 있습니다.', + 'vi': 'Chú ý: Ở cấp độ này chỉ nhánh master bị kiểm tra. Các nhánh khác chỉ dùng để tham chiếu(có dấu - ở nhãn). Như thường lệ, bạn có thể ẩn mục tiêu bằng "hide goal".', + 'sl_SI': 'Opomba: Samo master branch bo preverjen v tej stopnji. Ostali branchi so zgolj za referenco (prikazani kot črtaste oznake spodaj). Kot ponavadi, lahko skriješ dialog z "hide goal"', + 'pl': ' Uwaga: Na tym poziomie sprawdzana będzie tylko główna gałąź. Pozostałe gałęzie są tylko do odwołania (pokazane jako przerywane etykiety poniżej). Jak zawsze, możesz ukryć to okno dialogowe z "ukryj cel".' }, /////////////////////////////////////////////////////////////////////////// 'hide-goal': { @@ -1261,13 +1680,18 @@ exports.strings = { 'zh_CN': '你可以通过 "hide goal" 命令关闭这个窗口', 'zh_TW': '你可以透過 "hide goal" 關閉這個視窗', 'es_AR': 'Podés ocultar esta ventana con "hide goal"', + 'es_MX': 'Puedes ocultar esta ventana con "hide goal"', 'es_ES': 'Puedes ocultar esta ventana con "hide goal."', 'pt_BR': 'Você pode ocultar esta janela com "hide goal"', + 'gl' : 'Podes ocultar esta ventá con "hide goal"', 'fr_FR': 'Vous pouvez masquer cette fenêtre avec "Cacher les cibles"', 'ja' : 'このウィンドウは"hide goal"と打つかクリックで閉じれます', 'ru_RU': 'Можно скрыть это окно при помощи "hide goal"', 'uk': 'Можна сховати це вікно за допомогою "hide goal"', - 'ko': '"hide goal"을 사용하여 이 창을 숨길 수 있습니다.' + 'ko': '"hide goal"을 사용하여 이 창을 숨길 수 있습니다.', + 'vi': 'Bạn có thể ẩn cửa sổ này với "hide goal".', + 'sl_SI': 'To okno lahko skriješ z "hide goal"', + 'pl': 'Możesz ukryć to okno za pomocą opcji "ukryj cel"' }, /////////////////////////////////////////////////////////////////////////// 'hide-start': { @@ -1277,13 +1701,18 @@ exports.strings = { 'zh_CN': '你可以通过 "hide start" 命令关闭这个窗口', 'zh_TW': '你可以透過 "hide start" 關閉這個視窗', 'es_AR': 'Podés ocultar esta ventana con "hide start"', + 'es_MX': 'Puedes ocultar ésta ventana con "hide start"', 'es_ES': 'Puedes ocultar esta ventana con "hide start."', 'pt_BR': 'Você pode ocultar esta janela com "hide start"', + 'gl' : 'Podes ocultar esta ventá con "hide start"', 'fr_FR': 'Vous pouvez masquer cette fenêtre avec "hide start"', 'ja' : 'このウィンドウは"hide start"かクリックで閉じれます', 'ru_RU': 'Можно скрыть это окно при помощи "hide start"', 'uk': 'Можна сховати це вікно за допомогою "hide start"', - 'ko': '"hide start"를 사용하여 이 창을 숨길 수 있습니다.' + 'ko': '"hide start"를 사용하여 이 창을 숨길 수 있습니다.', + 'vi': 'Bạn có thể ẩn cửa sổ này với "hide start".', + 'sl_SI': 'To okno lahko skriješ z "hide start"', + 'pl': 'Możesz ukryć to okno za pomocą opcji "ukryj start"' }, /////////////////////////////////////////////////////////////////////////// 'level-builder': { @@ -1293,76 +1722,113 @@ exports.strings = { 'zh_CN': '关卡生成器', 'zh_TW': '關卡產生器', 'es_AR': 'Constructor de niveles', + 'es_MX': 'Constructor de niveles', 'es_ES': 'Constructor de niveles', 'pt_BR': 'Construtor de níveis', + 'gl' : 'Constructor de nivéis', 'fr_FR': 'Éditeur de niveaux', 'ja' : 'Levelエディタ', 'ru_RU': 'Редактор уровней', 'uk': 'Редактор рівнів', - 'ko': '레벨 생성기' + 'ko': '레벨 생성기', + 'vi': 'Trình tạo câp độ', + 'sl_SI': 'Graditelj Stopenj', + 'pl': 'Twórca poziomu' }, /////////////////////////////////////////////////////////////////////////// 'no-start-dialog': { '__desc__': 'when the user tries to open a start dialog for a level that does not have one', 'en_US': 'There is no start dialog to show for this level!', - 'de_DE': 'Es gibt keinen Einführungs-Dialog für diesen Level!', + 'de_DE': 'Es gibt keinen Einführungs-Dialog für dieses Level!', 'zh_CN': '这个关卡没有介绍!', 'zh_TW': '這關沒有介紹!', 'es_AR': '¡No hay mensaje de inicio para este nivel!', + 'es_MX': '¡No hay mensaje de inicio para éste nivel!', 'es_ES': '¡No hay mensaje de inicio para este nivel!', 'pt_BR': 'Não há mensagem de início para este nível!', + 'gl' : '¡Non hai mensaxe de inicio para este nivel!', 'fr_FR': 'Il n\'y a aucun dialogue de départ à afficher pour ce niveau !', 'ja' : 'このLevelにはスタートダイアログが存在しません', 'ru_RU': 'Нет стартового сообщение для уровня!', 'uk': 'Немає початкового діалогу для цього рівня!', - 'ko': '이 레벨을 위한 시작 대화창이 없습니다.' + 'ko': '이 레벨을 위한 시작 대화창이 없습니다.', + 'vi': 'Cấp độ này không được giới thiệu.', + 'sl_SI': 'Ni začetnega dialoga za prikaz te stopnje!', + 'pl': 'Dla tego poziomu nie ma okna startowego do wyświetlenia!' }, /////////////////////////////////////////////////////////////////////////// 'no-hint': { '__desc__': 'when no hint is available for a level', 'en_US': "Hmm, there doesn't seem to be a hint for this level :-/", - 'de_DE': "Hm, es gibt anscheinend keinen Hinweis für diesen Level :-/", + 'de_DE': "Hm, es gibt anscheinend keinen Hinweis für dieses Level :-/", 'zh_CN': "呃……,这关好像没有提示 :-/", 'zh_TW': "嗯‧‧‧這關沒有提示 :-/", 'es_AR': 'Mmm... Pareciera no haber pistas para este nivel :-/', + 'es_MX': 'Mmm... Parece que no hay pistas para éste nivel. :-/', 'es_ES': 'Mmm... Parece que no hay pistas para este nivel. :-/', 'pt_BR': 'Hmm, não existe nenhuma pista para este nível :-/', + 'gl' : 'Hmm, non existe ningunha pista para este nivel :-/', 'fr_FR': 'Hum, il ne semble pas y avoir d\'indice pour ce niveau :-/', 'ja' : 'あらら、このLevelでは、残念ながらヒントが存在しません :-/', 'ru_RU': "Милый мой, хороший, догадайся сам :-/ Подсказка не создана...", 'uk': 'Хм, схоже для цього рівня немає підказки :-/', - 'ko': '흠, 이 레벨을 위한 힌트가 없어보이는군요.' + 'ko': '흠, 이 레벨을 위한 힌트가 없어보이는군요.', + 'vi': 'Hmmm, có vẻ cấp độ này không có gợi ý rồi. :-/', + 'sl_SI': 'Hmm, izgleda da ni namiga za to stopnjo :-/', + 'pl': 'Hmm, wydaje się, że nie ma podpowiedzi dla tego poziomu :-/' }, /////////////////////////////////////////////////////////////////////////// 'error-untranslated-key': { '__desc__': 'This error happens when we are trying to translate a specific key and the locale version is mission', 'en_US': 'The translation for {key} does not exist yet :( Please hop on github and offer up a translation!', - 'de_DE': 'Die Übersetzung für {key} existiert noch nicht :( Falls du eine hast, bitte teil sie mit auf Github mit!', - 'zh_CN': '还没翻译 {key} :( 请在 Github 上贡献您的翻译!', - 'zh_TW': '還沒翻譯 {key} :( 請在 Github 上貢獻您的翻譯!', - 'es_AR': 'Aún no hay traducción para {key} :( ¡Metete en Github y sugerí una! :)', - 'es_ES': 'Aún no hay traducción para {key}. :( ¡Métete en Github y sugiere una! :)', - 'pt_BR': 'Não existe tradução para {key} :( Pule no Github e sugira uma! :)', - 'fr_FR': 'La traduction pour {key} n\'existe pas encore :( Venez sur Github pour en offrir une !', + 'de_DE': 'Die Übersetzung für {key} existiert noch nicht :( Falls du eine hast, dann teile sie mir bitte auf GitHub mit!', + 'zh_CN': '还没翻译 {key} :( 请在 GitHub 上贡献您的翻译!', + 'zh_TW': '還沒翻譯 {key} :( 請在 GitHub 上貢獻您的翻譯!', + 'es_AR': 'Aún no hay traducción para {key} :( ¡Metete en GitHub y sugerí una! :)', + 'es_MX': 'Aún no existe una traducción para {key}. :( ¡Métete en GitHub y sugiere una! :)', + 'es_ES': 'Aún no hay traducción para {key}. :( ¡Métete en GitHub y sugiere una! :)', + 'pt_BR': 'Não existe tradução para {key} :( Pule no GitHub e sugira uma! :)', + 'gl' : 'Non existe tradución para {key} :( Axúdanos en GitHub e suxire unha! :)', + 'fr_FR': 'La traduction pour {key} n\'existe pas encore :( Venez sur GitHub pour en offrir une !', 'ja' : '{key}の翻訳がまだ存在しません :( GitHubでの、翻訳の協力をお願いします m(_)m', 'ru_RU': 'Перевода для {key} не создано :( Пожалуйста, предложи перевод на GitHub', - 'uk': 'Немає перекладу для {key} :( Будь-ласка, запропонуй переклад на Github', - 'ko': '{key}를 위한 번역은 아직 존재하지 않습니다 :( 번역에 참여해주세요!' + 'uk': 'Немає перекладу для {key} :( Будь-ласка, запропонуй переклад на GitHub', + 'ko': '{key}를 위한 번역은 아직 존재하지 않습니다 :( 번역에 참여해주세요!', + 'vi': 'Bản dịch cho {key} không có rồi :( Nếu có thể thì hãy lên dự án của chúng tôi ở GitHub để cung cấp bản dịch!', + 'sl_SI': 'Prevod za {key} še ne obstaja :( Skoči na github in dodaj prevod!', + 'pl': 'Tłumaczenie dla klucza "{key}" jeszcze nie istnieje tłumaczenia :( Zapraszam na GitHub, aby pomóc w tłumaczeniu!' }, /////////////////////////////////////////////////////////////////////////// 'error-untranslated': { '__desc__': 'The general error when we encounter a dialog that is not translated', 'en_US': 'This dialog or text is not yet translated in your locale :( Hop on github to aid in translation!', - 'de_DE': 'Dieser Dialog oder Text ist noch nicht in deine Sprache übersetzt. :( Schau auf Github vorbei um bei der Übersetzung zu helfen!', - 'zh_CN': '这段对话还没有被翻译成您的语言 :( 欢迎在 Github 上贡献您的翻译!', - 'zh_TW': '這段對話尚未翻成您的語言 :( 歡迎到 Github 貢獻翻譯!', - 'es_AR': 'Este mensaje o texto aún no fue traducido a tu idioma :( ¡Metete en Github y ayudanos a traducirlo!', - 'es_ES': 'Este mensaje o texto aún no fue traducido a tu idioma. :( ¡Métete en Github y ayúdanos a traducirlo!', - 'pt_BR': 'Esta mensagem ou texto não foi traduzida para Português :( Ajude-nos a traduzir no Github!', - 'fr_FR': 'Ce message n\'a pas encore été traduit dans votre langue :( Venez sur Github aider à la traduction !', + 'de_DE': 'Dieser Dialog oder Text ist noch nicht in deiner Sprache verfügbar. :( Schau auf GitHub vorbei um bei der Übersetzung zu helfen!', + 'zh_CN': '这段对话还没有被翻译成您的语言 :( 欢迎在 GitHub 上贡献您的翻译!', + 'zh_TW': '這段對話尚未翻成您的語言 :( 歡迎到 GitHub 貢獻翻譯!', + 'es_AR': 'Este mensaje o texto aún no fue traducido a tu idioma :( ¡Metete en GitHub y ayudanos a traducirlo!', + 'es_MX': 'Este mensaje o texto aún no ha sido traducido en tu idioma. :( ¡Métete en GitHub y ayúdanos a traducirlo!', + 'es_ES': 'Este mensaje o texto aún no fue traducido a tu idioma. :( ¡Métete en GitHub y ayúdanos a traducirlo!', + 'pt_BR': 'Esta mensagem ou texto não foi traduzida para Português :( Ajude-nos a traduzir no GitHub!', + 'gl' : 'Esta mensaxe ou texto non foi traducida ó teu idioma :( Axúdanos a traducir a web en GitHub, é moi doado!', + 'fr_FR': 'Ce message n\'a pas encore été traduit dans votre langue :( Venez sur GitHub aider à la traduction !', 'ja' : 'このダイアログ、またはテキストの翻訳がまだ存在しません :( GitHubでの、翻訳の協力をお願いします m(_)m', 'ru_RU': 'Для этого сообщения нет перевода :( Пожалуйста, предложи перевод на GitHub', - 'uk': 'Для цього повідомлення ще немає перекладу :( Будь-ласка, запропонуй переклад на Github', - 'ko': '이 대화창이나 텍스트는 아직 번역되지 않았습니다. :( 번역에 참여해주세요!' + 'uk': 'Для цього повідомлення ще немає перекладу :( Будь-ласка, запропонуй переклад на GitHub', + 'ko': '이 대화창이나 텍스트는 아직 번역되지 않았습니다. :( 번역에 참여해주세요!', + 'vi': 'Hội thoại hoặc văn bản này chưa được dịch ra ngôn ngữ của bạn rồi. :( Hãy lên GitHub để cung cấp bản dịch!', + 'sl_SI': 'Ta dialog ali tekst še ni preveden za tvoj jezik :( Skoči na github in dodaj prevod!', + 'pl' : 'Kolejne okno dialogowe lub tekst nie zostało jeszcze przetłumaczone na język polski :( Zapraszam na GitHub, aby pomóc w tłumaczeniu!' + }, + /////////////////////////////////////////////////////////////////////////// + 'cancel-button': { + '__desc__': 'Cancel button label after completing a level', + 'en_US': 'Cancel', + 'pl' : 'Powrót' + }, + /////////////////////////////////////////////////////////////////////////// + 'confirm-button': { + '__desc__': 'Confirm button label after completing a level', + 'en_US': 'Confirm', + 'pl' : 'Dalej' } }; diff --git a/src/js/level/builder.js b/src/js/level/builder.js index d3e7b1a2..a47dd7b8 100644 --- a/src/js/level/builder.js +++ b/src/js/level/builder.js @@ -1,4 +1,3 @@ -var _ = require('underscore'); var Backbone = require('backbone'); var Q = require('q'); @@ -55,7 +54,7 @@ var LevelBuilder = Level.extend({ // if we are editing a level our behavior is a bit different var editLevelJSON; if (options.editLevel) { - LevelStore.getLevel(options.editLevel); + editLevelJSON = LevelStore.getLevel(options.editLevel); options.level = editLevelJSON; } @@ -68,7 +67,7 @@ var LevelBuilder = Level.extend({ this.definedGoal = true; } - // we wont be using this stuff, and it is deleted to ensure we overwrite all functions that + // we won't be using this stuff, and it is deleted to ensure we overwrite all functions that // include that functionality delete this.treeCompare; delete this.solved; @@ -271,7 +270,7 @@ var LevelBuilder = Level.extend({ this.startDialogObj = levelObj; }.bind(this)) .fail(function() { - // nothing to do, they dont want to edit it apparently + // nothing to do, they don't want to edit it apparently }) .done(function() { if (command) { @@ -335,12 +334,12 @@ var LevelBuilder = Level.extend({ .then(function() { // oh boy this is complex var whenEditedDialog = Q.defer(); - // the undefined here is the command that doesnt need resolving just yet... + // the undefined here is the command that doesn't need resolving just yet... this.editDialog(undefined, whenEditedDialog); return whenEditedDialog.promise; }.bind(this)) .fail(function() { - // if they dont want to edit the start dialog, do nothing + // if they don't want to edit the start dialog, do nothing }) .done(function() { askForStartDeferred.resolve(); @@ -360,7 +359,7 @@ var LevelBuilder = Level.extend({ }, getExportObj: function() { - var compiledLevel = _.extend( + var compiledLevel = Object.assign( {}, this.level ); @@ -385,14 +384,14 @@ var LevelBuilder = Level.extend({ 'help builder': LevelBuilder.__super__.startDialog }; if (!methodMap[command.get('method')]) { - throw new Error('woah we dont support that method yet'); + throw new Error('woah we don\'t support that method yet'); } methodMap[command.get('method')].apply(this, arguments); }, afterCommandDefer: function(defer, command) { - // we dont need to compare against the goal anymore + // we don't need to compare against the goal anymore defer.resolve(); }, diff --git a/src/js/level/index.js b/src/js/level/index.js index 3466ce66..e17be7b5 100644 --- a/src/js/level/index.js +++ b/src/js/level/index.js @@ -1,12 +1,12 @@ -var _ = require('underscore'); var Q = require('q'); +var React = require('react'); +var ReactDOM = require('react-dom'); var util = require('../util'); var Main = require('../app'); var intl = require('../intl'); var log = require('../log'); -var React = require('react'); var Errors = require('../util/errors'); var Sandbox = require('../sandbox/').Sandbox; var GlobalStateActions = require('../actions/GlobalStateActions'); @@ -69,8 +69,15 @@ var Level = Sandbox.extend({ // if there is a multiview in the beginning, open that // and let it resolve our deferred + if (GlobalStateStore.getShouldDisableLevelInstructions()) { + setTimeout(function() { + deferred.resolve(); + }, 100); + return; + } + if (this.level.startDialog && !this.testOption('noIntroDialog')) { - new MultiView(_.extend( + new MultiView(Object.assign( {}, intl.getStartDialog(this.level), { deferred: deferred } @@ -99,7 +106,7 @@ var Level = Sandbox.extend({ var dialog = $.extend({}, intl.getStartDialog(levelObj)); // grab the last slide only dialog.childViews = dialog.childViews.slice(-1); - new MultiView(_.extend( + new MultiView(Object.assign( dialog, { deferred: deferred } )); @@ -140,7 +147,7 @@ var Level = Sandbox.extend({ parent: this } ); - React.render( + ReactDOM.render( this.levelToolbar, document.getElementById('levelToolbarMount') ); @@ -166,6 +173,14 @@ var Level = Sandbox.extend({ startOffCommand: function() { var method = this.options.command.get('method'); + if (GlobalStateStore.getShouldDisableLevelInstructions()) { + Main.getEventBaton().trigger( + 'commandSubmitted', + 'hint; show goal' + ); + return; + } + if (!this.testOption('noStartCommand') && method !== 'importLevelNow') { Main.getEventBaton().trigger( 'commandSubmitted', @@ -401,13 +416,14 @@ var Level = Sandbox.extend({ doesCommandCountTowardsTotal: function(command) { if (command.get('error')) { - // dont count errors towards our count + // don't count errors towards our count return false; } var matched = false; - _.each(Commands.commands.getCommandsThatCount(), function(map) { - _.each(map, function(regex) { + var commandsThatCount = Commands.commands.getCommandsThatCount(); + Object.values(commandsThatCount).forEach(function(map) { + Object.values(map).forEach(function(regex) { matched = matched || regex.test(command.get('rawStr')); }); }); @@ -497,7 +513,7 @@ var Level = Sandbox.extend({ finishAnimationChain = deferred.promise; Main.getEventBaton().trigger( 'commandSubmitted', - 'echo "level solved!"' + 'echo "level solved! type in \'levels\' to access the next level"' ); } else { GlobalStateActions.changeIsAnimating(true); @@ -543,7 +559,7 @@ var Level = Sandbox.extend({ }, die: function() { - React.unmountComponentAtNode( + ReactDOM.unmountComponentAtNode( document.getElementById('levelToolbarMount') ); @@ -645,7 +661,7 @@ var Level = Sandbox.extend({ }; var method = methodMap[command.get('method')]; if (!method) { - throw new Error('woah we dont support that method yet', method); + throw new Error('woah we don\'t support that method yet', method); } method.apply(this, [command, defer]); diff --git a/src/js/level/parseWaterfall.js b/src/js/level/parseWaterfall.js index da48b6f9..b58e7e00 100644 --- a/src/js/level/parseWaterfall.js +++ b/src/js/level/parseWaterfall.js @@ -1,5 +1,3 @@ -var _ = require('underscore'); - var GitCommands = require('../git/commands'); var Commands = require('../commands'); var SandboxCommands = require('../sandbox/commands'); @@ -27,7 +25,7 @@ ParseWaterfall.prototype.initParseWaterfall = function() { return; } - // by deferring the initialization here, we dont require() + // by deferring the initialization here, we don't require() // level too early (which barfs our init) this.parseWaterfall = this.options.parseWaterfall || [ Commands.parse, @@ -68,15 +66,17 @@ ParseWaterfall.prototype.addLast = function(which, value) { }; ParseWaterfall.prototype.expandAllShortcuts = function(commandStr) { - _.each(this.shortcutWaterfall, function(shortcutMap) { + this.shortcutWaterfall.forEach(function(shortcutMap) { commandStr = this.expandShortcut(commandStr, shortcutMap); }, this); return commandStr; }; ParseWaterfall.prototype.expandShortcut = function(commandStr, shortcutMap) { - _.each(shortcutMap, function(map, vcs) { - _.each(map, function(regex, method) { + Object.keys(shortcutMap).forEach(function(vcs) { + var map = shortcutMap[vcs]; + Object.keys(map).forEach(function(method) { + var regex = map[method]; var results = regex.exec(commandStr); if (results) { commandStr = vcs + ' ' + method + ' ' + commandStr.slice(results[0].length); @@ -87,13 +87,13 @@ ParseWaterfall.prototype.expandShortcut = function(commandStr, shortcutMap) { }; ParseWaterfall.prototype.processAllInstants = function(commandStr) { - _.each(this.instantWaterfall, function(instantCommands) { + this.instantWaterfall.forEach(function(instantCommands) { this.processInstant(commandStr, instantCommands); }, this); }; ParseWaterfall.prototype.processInstant = function(commandStr, instantCommands) { - _.each(instantCommands, function(tuple) { + instantCommands.forEach(function(tuple) { var regex = tuple[0]; var results = regex.exec(commandStr); if (results) { @@ -109,7 +109,7 @@ ParseWaterfall.prototype.parseAll = function(commandStr) { } var toReturn = false; - _.each(this.parseWaterfall, function(parseFunc) { + this.parseWaterfall.forEach(function(parseFunc) { var results = parseFunc(commandStr); if (results) { toReturn = results; @@ -120,4 +120,3 @@ ParseWaterfall.prototype.parseAll = function(commandStr) { }; exports.ParseWaterfall = ParseWaterfall; - diff --git a/src/js/mercurial/commands.js b/src/js/mercurial/commands.js index acf14fcc..cc9140a6 100644 --- a/src/js/mercurial/commands.js +++ b/src/js/mercurial/commands.js @@ -206,7 +206,7 @@ var commandConfig = { }; } }, - + backout: { regex: /^hg +backout($|\s+)/, options: [ diff --git a/src/js/models/commandModel.js b/src/js/models/commandModel.js index 9fd1a104..c487281d 100644 --- a/src/js/models/commandModel.js +++ b/src/js/models/commandModel.js @@ -1,9 +1,9 @@ -var _ = require('underscore'); var Backbone = require('backbone'); var Errors = require('../util/errors'); var ParseWaterfall = require('../level/parseWaterfall').ParseWaterfall; +var LevelStore = require('../stores/LevelStore'); var intl = require('../intl'); var CommandProcessError = Errors.CommandProcessError; @@ -43,7 +43,7 @@ var Command = Backbone.Model.extend({ }, initDefaults: function() { - // weird things happen with defaults if you dont + // weird things happen with defaults if you don't // make new objects this.set('generalArgs', []); this.set('supportedMap', {}); @@ -77,13 +77,14 @@ var Command = Backbone.Model.extend({ mapDotToHead: function() { var generalArgs = this.getGeneralArgs(); var options = this.getOptionsMap(); - - generalArgs = _.map(generalArgs, function(arg) { + + generalArgs = generalArgs.map(function(arg) { return this.replaceDotWithHead(arg); }, this); var newMap = {}; - _.each(options, function(args, key) { - newMap[key] = _.map(args, function(arg) { + Object.keys(options).forEach(function(key) { + var args = options[key]; + newMap[key] = Object.values(args).map(function (arg) { return this.replaceDotWithHead(arg); }, this); }, this); @@ -93,7 +94,7 @@ var Command = Backbone.Model.extend({ deleteOptions: function(options) { var map = this.getOptionsMap(); - _.each(options, function(option) { + options.forEach(function(option) { delete map[option]; }, this); this.setOptionsMap(map); @@ -126,18 +127,14 @@ var Command = Backbone.Model.extend({ oneArgImpliedHead: function(args, option) { this.validateArgBounds(args, 0, 1, option); // and if it's one, add a HEAD to the back - if (args.length === 0) { - args.push('HEAD'); - } + this.impliedHead(args, 0); }, twoArgsImpliedHead: function(args, option) { // our args we expect to be between 1 and 2 this.validateArgBounds(args, 1, 2, option); // and if it's one, add a HEAD to the back - if (args.length == 1) { - args.push('HEAD'); - } + this.impliedHead(args, 1); }, oneArgImpliedOrigin: function(args) { @@ -151,6 +148,12 @@ var Command = Backbone.Model.extend({ this.validateArgBounds(args, 0, 2); }, + impliedHead: function(args, min) { + if(args.length == min) { + args.push('HEAD'); + } + }, + // this is a little utility class to help arg validation that happens over and over again validateArgBounds: function(args, lower, upper, option) { var what = (option === undefined) ? @@ -265,15 +268,26 @@ var Command = Backbone.Model.extend({ }, parseAll: function() { - var str = this.get('rawStr'); - var results = this.get('parseWaterfall').parseAll(str); + var rawInput = this.get('rawStr'); + const aliasMap = LevelStore.getAliasMap(); + for (var i = 0; i this.clearOldCommands(), this); + } - componentWillUnmount: function() { + componentWillUnmount() { for (var i = 0; i < _subscribeEvents.length; i++) { this.props.commandCollection.off( _subscribeEvents[i], @@ -38,13 +35,13 @@ var CommandHistoryView = React.createClass({ this ); } - }, + } - updateFromCollection: function() { + updateFromCollection() { this.forceUpdate(); - }, + } - render: function() { + render() { var allCommands = []; this.props.commandCollection.each(function(command, index) { allCommands.push( @@ -60,9 +57,9 @@ var CommandHistoryView = React.createClass({ {allCommands}
); - }, + } - scrollDown: function() { + scrollDown() { var cD = document.getElementById('commandDisplay'); var t = document.getElementById('terminal'); @@ -81,9 +78,9 @@ var CommandHistoryView = React.createClass({ if (shouldScroll) { t.scrollTop = t.scrollHeight; } - }, + } - clearOldCommands: function() { + clearOldCommands() { // go through and get rid of every command that is "processed" or done var toDestroy = []; @@ -100,6 +97,11 @@ var CommandHistoryView = React.createClass({ this.scrollDown(); } -}); +} + +CommandHistoryView.propTypes = { + // the backbone command model collection + commandCollection: PropTypes.object.isRequired +}; module.exports = CommandHistoryView; diff --git a/src/js/react_views/CommandView.jsx b/src/js/react_views/CommandView.jsx index 362c4a6e..7fbf6e2b 100644 --- a/src/js/react_views/CommandView.jsx +++ b/src/js/react_views/CommandView.jsx @@ -1,7 +1,9 @@ var React = require('react'); +var ReactDOM = require('react-dom'); +var PropTypes = require('prop-types'); var reactUtil = require('../util/reactUtil'); -var keyMirror = require('react/lib/keyMirror'); +var keyMirror = require('../util/keyMirror'); var STATUSES = keyMirror({ inqueue: null, @@ -9,39 +11,18 @@ var STATUSES = keyMirror({ finished: null }); -var CommandView = React.createClass({ +class CommandView extends React.Component{ - propTypes: { - // the backbone command model - command: React.PropTypes.object.isRequired, - id: React.PropTypes.string, - }, - - componentDidMount: function() { + componentDidMount() { this.props.command.on('change', this.updateStateFromModel, this); - this.props.command.on('destroy', this.onModelDestroy, this); this.updateStateFromModel(); - }, + } - componentWillUnmount: function() { + componentWillUnmount() { this.props.command.off('change', this.updateStateFromModel, this); - this.props.command.off('destroy', this.onModelDestroy, this); - }, + } - onModelDestroy: function() { - if (!this.isMounted()) { - return; - } - if (!this.getDOMNode) { - // WTF -- only happens in casperjs tests weirdly - console.error('this.getDOMNode not a function?'); - return; - } - - React.unmountComponentAtNode(this.getDOMNode().parentNode); - }, - - updateStateFromModel: function() { + updateStateFromModel() { var commandJSON = this.props.command.toJSON(); this.setState({ status: commandJSON.status, @@ -49,18 +30,19 @@ var CommandView = React.createClass({ warnings: commandJSON.warnings, result: commandJSON.result }); - }, + } - getInitialState: function() { - return { + constructor(props, context) { + super(props, context); + this.state = { status: STATUSES.inqueue, rawStr: 'git commit', warnings: [], result: '' }; - }, + } - render: function() { + render() { var commandClass = reactUtil.joinClasses([ this.state.status, 'commandLine', @@ -89,9 +71,9 @@ var CommandView = React.createClass({ ); - }, + } - renderResult: function() { + renderResult() { if (!this.state.result) { return null; } @@ -100,23 +82,35 @@ var CommandView = React.createClass({ var paragraphs = this.state.result.split("\n"); var result = []; for (var i = 0; i < paragraphs.length; i++) { - result.push( -

- ); + if (paragraphs[i].startsWith('https://')) { + result.push( + + ); + } else { + result.push( +

+ ); + } } return (

); - }, + } - renderFormattedWarnings: function() { + renderFormattedWarnings() { var warnings = this.state.warnings; var result = []; for (var i = 0; i < warnings.length; i++) { @@ -129,6 +123,12 @@ var CommandView = React.createClass({ } return result; } -}); +}; + +CommandView.propTypes = { + // the backbone command model + command: PropTypes.object.isRequired, + id: PropTypes.string, +}; module.exports = CommandView; diff --git a/src/js/react_views/CommandsHelperBarView.jsx b/src/js/react_views/CommandsHelperBarView.jsx index 4982d56e..a3c43fe0 100644 --- a/src/js/react_views/CommandsHelperBarView.jsx +++ b/src/js/react_views/CommandsHelperBarView.jsx @@ -1,31 +1,27 @@ +var React = require('react'); +var PropTypes = require('prop-types'); var HelperBarView = require('../react_views/HelperBarView.jsx'); var Main = require('../app'); -var React = require('react'); var log = require('../log'); -var CommandsHelperBarView = React.createClass({ +class CommandsHelperBarView extends React.Component { - propTypes: { - shown: React.PropTypes.bool.isRequired, - onExit: React.PropTypes.func.isRequired - }, - - render: function() { + render() { return ( ); - }, + } - fireCommand: function(command) { + fireCommand(command) { log.viewInteracted('commandHelperBar'); Main.getEventBaton().trigger('commandSubmitted', command); - }, + } - getItems: function() { + getItems() { return [{ text: 'Levels', onClick: function() { @@ -64,6 +60,11 @@ var CommandsHelperBarView = React.createClass({ }]; } -}); +}; + +CommandsHelperBarView.propTypes = { + shown: PropTypes.bool.isRequired, + onExit: PropTypes.func.isRequired +}; module.exports = CommandsHelperBarView; diff --git a/src/js/react_views/HelperBarView.jsx b/src/js/react_views/HelperBarView.jsx index 7f1f4016..1e63df73 100644 --- a/src/js/react_views/HelperBarView.jsx +++ b/src/js/react_views/HelperBarView.jsx @@ -1,16 +1,11 @@ var React = require('react'); +var PropTypes = require('prop-types'); var reactUtil = require('../util/reactUtil'); -var HelperBarView = React.createClass({ +class HelperBarView extends React.Component { - propTypes: { - className: React.PropTypes.string, - shown: React.PropTypes.bool.isRequired, - items: React.PropTypes.array.isRequired - }, - - render: function() { + render() { var topClassName = reactUtil.joinClasses([ 'helperBar', 'transitionAll', @@ -32,9 +27,9 @@ var HelperBarView = React.createClass({ }.bind(this))} ); - }, + } - renderItem: function(item, index) { + renderItem(item, index) { var testID = item.icon || item.testID || item.text.toLowerCase(); if (item.newPageLink) { @@ -63,6 +58,13 @@ var HelperBarView = React.createClass({ ); } -}); +}; + +HelperBarView.propTypes = { + className: PropTypes.string, + shown: PropTypes.bool.isRequired, + items: PropTypes.array.isRequired +}; + module.exports = HelperBarView; diff --git a/src/js/react_views/IntlHelperBarView.jsx b/src/js/react_views/IntlHelperBarView.jsx index 7b9a1cf7..170492c1 100644 --- a/src/js/react_views/IntlHelperBarView.jsx +++ b/src/js/react_views/IntlHelperBarView.jsx @@ -1,32 +1,29 @@ +var PropTypes = require('prop-types'); + var HelperBarView = require('../react_views/HelperBarView.jsx'); var Main = require('../app'); var React = require('react'); var log = require('../log'); -var IntlHelperBarView = React.createClass({ +class IntlHelperBarView extends React.Component{ - propTypes: { - shown: React.PropTypes.bool.isRequired, - onExit: React.PropTypes.func.isRequired - }, - - render: function() { + render() { return ( ); - }, + } - fireCommand: function(command) { + fireCommand(command) { log.viewInteracted('intlSelect'); Main.getEventBaton().trigger('commandSubmitted', command); this.props.onExit(); - }, + } - getItems: function() { + getItems() { return [{ text: 'Git Branching', testID: 'english', @@ -60,9 +57,21 @@ var IntlHelperBarView = React.createClass({ }, { text: 'español', testID: 'spanish', + onClick: function() { + this.fireCommand('locale es_ES; levels'); + }.bind(this) + }, { + text: 'argentino', + testID: 'argentinian', onClick: function() { this.fireCommand('locale es_AR; levels'); }.bind(this) + }, { + text: 'mexicano', + testID: 'mexican', + onClick: function() { + this.fireCommand('locale es_MX; levels'); + }.bind(this) }, { text: 'português', testID: 'portuguese', @@ -93,14 +102,50 @@ var IntlHelperBarView = React.createClass({ onClick: function() { this.fireCommand('locale uk; levels'); }.bind(this) + }, { + text: 'Tiếng Việt', + testID: 'vietnamese', + onClick: function() { + this.fireCommand('locale vi; levels'); + }.bind(this) + }, { + text: 'Galego', + testID: 'galician', + onClick: function() { + this.fireCommand('locale gl; levels'); + }.bind(this) + }, { + text: 'Slovensko', + testID: 'slovenian', + onClick: function() { + this.fireCommand('locale sl_SI; levels'); + }.bind(this) + }, { + text: 'Polski', + testID: 'polish', + onClick: function() { + this.fireCommand('locale pl; levels'); + }.bind(this) + }, { + text: 'தமிழ்', + testID: 'tamil', + onClick: function() { + this.fireCommand('locale ta_IN; levels'); + }.bind(this) }, { icon: 'signout', onClick: function() { this.props.onExit(); }.bind(this) - }]; + } + ]; } -}); +}; + +IntlHelperBarView.propTypes = { + shown: PropTypes.bool.isRequired, + onExit: PropTypes.func.isRequired +} module.exports = IntlHelperBarView; diff --git a/src/js/react_views/LevelToolbarView.jsx b/src/js/react_views/LevelToolbarView.jsx index 48dd56dd..b498df63 100644 --- a/src/js/react_views/LevelToolbarView.jsx +++ b/src/js/react_views/LevelToolbarView.jsx @@ -1,31 +1,30 @@ var React = require('react'); -var PropTypes = React.PropTypes; +var PropTypes = require('prop-types'); var intl = require('../intl'); var reactUtil = require('../util/reactUtil'); -var LevelToolbarView = React.createClass({ +class LevelToolbarView extends React.Component { - propTypes: { - name: PropTypes.string.isRequired, - onGoalClick: PropTypes.func.isRequired, - onObjectiveClick: PropTypes.func.isRequired, - parent: PropTypes.object.isRequired - }, - - getInitialState: function() { - return { + constructor(props, context) { + super(props, context); + this.state = { isHidden: true, isGoalExpanded: this.props.parent.getIsGoalExpanded() }; - }, + } - componentDidMount: function() { + componentWillUnmount() { + this._isMounted = false; + } + componentDidMount() { + this._isMounted = true; this.setState({ - isHidden: this.props.parent.getIsGoalExpanded() + isHidden: this.props.parent.getIsGoalExpanded(), + isGoalExpanded: this.props.parent.getIsGoalExpanded() }); this.props.parent.on('goalToggled', function() { - if (!this.isMounted()) { + if (!this._isMounted) { return; } @@ -33,9 +32,9 @@ var LevelToolbarView = React.createClass({ isGoalExpanded: this.props.parent.getIsGoalExpanded() }); }.bind(this)); - }, + } - render: function() { + render() { return (
- {this.state.isGoalExpanded ? + {this.state.isGoalExpanded ? intl.str('hide-goal-button') : intl.str('show-goal-button') } @@ -78,6 +77,13 @@ var LevelToolbarView = React.createClass({ ); } -}); +}; + +LevelToolbarView.propTypes = { + name: PropTypes.string.isRequired, + onGoalClick: PropTypes.func.isRequired, + onObjectiveClick: PropTypes.func.isRequired, + parent: PropTypes.object.isRequired +} module.exports = LevelToolbarView; diff --git a/src/js/react_views/MainHelperBarView.jsx b/src/js/react_views/MainHelperBarView.jsx index d502c0e9..1b7bb0f8 100644 --- a/src/js/react_views/MainHelperBarView.jsx +++ b/src/js/react_views/MainHelperBarView.jsx @@ -14,15 +14,16 @@ var BARS = keyMirror({ COMMANDS: null }); -var MainHelperBarView = React.createClass({ +class MainHelperBarView extends React.Component { - getInitialState: function() { - return { + constructor(props, context) { + super(props, context); + this.state = { shownBar: BARS.SELF }; - }, + } - render: function() { + render() { return (
); - }, + } - showSelf: function() { + showSelf() { this.setState({ shownBar: BARS.SELF }); - }, + } - getItems: function() { + getItems() { return [{ icon: 'question-sign', onClick: function() { @@ -74,6 +75,6 @@ var MainHelperBarView = React.createClass({ }]; } -}); +}; module.exports = MainHelperBarView; diff --git a/src/js/sandbox/commands.js b/src/js/sandbox/commands.js index 6da2b6a6..24158874 100644 --- a/src/js/sandbox/commands.js +++ b/src/js/sandbox/commands.js @@ -1,4 +1,3 @@ -var _ = require('underscore'); var util = require('../util'); var constants = require('../util/constants'); @@ -9,6 +8,7 @@ var Errors = require('../util/errors'); var CommandProcessError = Errors.CommandProcessError; var LocaleStore = require('../stores/LocaleStore'); var LocaleActions = require('../actions/LocaleActions'); +var LevelStore = require('../stores/LevelStore'); var GlobalStateStore = require('../stores/GlobalStateStore'); var GlobalStateActions = require('../actions/GlobalStateActions'); var GitError = Errors.GitError; @@ -16,12 +16,12 @@ var Warning = Errors.Warning; var CommandResult = Errors.CommandResult; var instantCommands = [ - [/^ls/, function() { + [/^ls( |$)/, function() { throw new CommandResult({ msg: intl.str('ls-command') }); }], - [/^cd/, function() { + [/^cd( |$)/, function() { throw new CommandResult({ msg: intl.str('cd-command') }); @@ -51,6 +51,21 @@ var instantCommands = [ msg: lines.join('\n') }); }], + [/^alias (\w+)="(.+)"$/, function(bits) { + const alias = bits[1]; + const expansion = bits[2]; + LevelStore.addToAliasMap(alias, expansion); + throw new CommandResult({ + msg: 'Set alias "'+alias+'" to "'+expansion+'"', + }); + }], + [/^unalias (\w+)$/, function(bits) { + const alias = bits[1]; + LevelStore.removeFromAliasMap(alias); + throw new CommandResult({ + msg: 'Removed alias "'+alias+'"', + }); + }], [/^locale (\w+)$/, function(bits) { LocaleActions.changeLocale(bits[1]); throw new CommandResult({ @@ -69,6 +84,12 @@ var instantCommands = [ msg: intl.str('flip-tree-command') }); }], + [/^disableLevelInstructions$/, function() { + GlobalStateActions.disableLevelInstructions(); + throw new CommandResult({ + msg: intl.todo('Level instructions disabled'), + }); + }], [/^refresh$/, function() { var events = require('../app').getEvents(); @@ -98,9 +119,10 @@ var instantCommands = [ intl.str('show-all-commands'), '
' ]; - _.each(allCommands, function(regex, command) { - lines.push(command); - }); + Object.keys(allCommands) + .forEach(function(command) { + lines.push(command); + }); throw new CommandResult({ msg: lines.join('\n') @@ -134,17 +156,20 @@ var getAllCommands = function() { 'mobileAlert' ]; - var allCommands = _.extend( + var allCommands = Object.assign( {}, require('../level').regexMap, regexMap ); - _.each(Commands.commands.getRegexMap(), function(map, vcs) { - _.each(map, function(regex, method) { + var mRegexMap = Commands.commands.getRegexMap(); + Object.keys(mRegexMap).forEach(function(vcs) { + var map = mRegexMap[vcs]; + Object.keys(map).forEach(function(method) { + var regex = map[method]; allCommands[vcs + ' ' + method] = regex; }); }); - _.each(toDelete, function(key) { + toDelete.forEach(function(key) { delete allCommands[key]; }); diff --git a/src/js/sandbox/index.js b/src/js/sandbox/index.js index c9131e23..c85d5f44 100644 --- a/src/js/sandbox/index.js +++ b/src/js/sandbox/index.js @@ -228,12 +228,21 @@ var Sandbox = Backbone.View.extend({ var url = 'https://learngitbranching.js.org/?NODEMO&command=importTreeNow%20' + escape(treeJSON); command.setResult( - intl.todo('Here is a link to the current state of the tree: ') + url + intl.todo('Here is a link to the current state of the tree: ') + '\n' + url ); command.finishWith(deferred); }, resetSolved: function(command, deferred) { + if (command.get('regexResults').input !== 'reset solved --confirm') { + command.set('error', new Errors.GitError({ + msg: 'Reset solved will mark each level as not yet solved; because ' + + 'this is a destructive command, please pass in --confirm to execute', + })); + command.finishWith(deferred); + return; + } + LevelActions.resetLevelsSolved(); command.addWarning( intl.str('solved-map-reset') diff --git a/src/js/stores/CommandLineStore.js b/src/js/stores/CommandLineStore.js index c97e80d6..a2cf9fa1 100644 --- a/src/js/stores/CommandLineStore.js +++ b/src/js/stores/CommandLineStore.js @@ -4,8 +4,6 @@ var AppConstants = require('../constants/AppConstants'); var AppDispatcher = require('../dispatcher/AppDispatcher'); var EventEmitter = require('events').EventEmitter; -var assign = require('object-assign'); - var ActionTypes = AppConstants.ActionTypes; var COMMAND_HISTORY_KEY = 'lgb_CommandHistory'; var COMMAND_HISTORY_MAX_LENGTH = 100; @@ -38,7 +36,7 @@ function _saveToLocalStorage() { } } -var CommandLineStore = assign( +var CommandLineStore = Object.assign( {}, EventEmitter.prototype, AppConstants.StoreSubscribePrototype, diff --git a/src/js/stores/GlobalStateStore.js b/src/js/stores/GlobalStateStore.js index 35897d2d..74f4e47f 100644 --- a/src/js/stores/GlobalStateStore.js +++ b/src/js/stores/GlobalStateStore.js @@ -4,15 +4,14 @@ var AppConstants = require('../constants/AppConstants'); var AppDispatcher = require('../dispatcher/AppDispatcher'); var EventEmitter = require('events').EventEmitter; -var assign = require('object-assign'); - var ActionTypes = AppConstants.ActionTypes; var _isAnimating = false; var _flipTreeY = false; var _numLevelsSolved = 0; +var _disableLevelInstructions = false; -var GlobalStateStore = assign( +var GlobalStateStore = Object.assign( {}, EventEmitter.prototype, AppConstants.StoreSubscribePrototype, @@ -29,6 +28,10 @@ AppConstants.StoreSubscribePrototype, return _numLevelsSolved; }, + getShouldDisableLevelInstructions: function() { + return _disableLevelInstructions; + }, + dispatchToken: AppDispatcher.register(function(payload) { var action = payload.action; var shouldInform = false; @@ -46,6 +49,10 @@ AppConstants.StoreSubscribePrototype, _numLevelsSolved++; shouldInform = true; break; + case ActionTypes.DISABLE_LEVEL_INSTRUCTIONS: + _disableLevelInstructions = true; + shouldInform = true; + break; } if (shouldInform) { diff --git a/src/js/stores/LevelStore.js b/src/js/stores/LevelStore.js index dccf6d84..6c184ddf 100644 --- a/src/js/stores/LevelStore.js +++ b/src/js/stores/LevelStore.js @@ -3,19 +3,43 @@ var AppConstants = require('../constants/AppConstants'); var AppDispatcher = require('../dispatcher/AppDispatcher'); var EventEmitter = require('events').EventEmitter; - -var _ = require('underscore'); -var assign = require('object-assign'); var levelSequences = require('../../levels').levelSequences; var sequenceInfo = require('../../levels').sequenceInfo; +var util = require('../util'); var ActionTypes = AppConstants.ActionTypes; var SOLVED_MAP_STORAGE_KEY = 'solvedMap'; +var ALIAS_STORAGE_KEY = 'aliasMap'; var _levelMap = {}; var _solvedMap = {}; var _sequences = []; +if (!util.isBrowser()) { + // https://stackoverflow.com/a/26177872/6250402 + var storage = {}; + var localStorage = { + setItem: function(key, value) { + storage[key] = value || ''; + }, + getItem: function(key) { + return key in storage ? storage[key] : null; + }, + removeItem: function(key) { + delete storage[key]; + }, + get length() { + return Object.keys(storage).length; + }, + key: function(i) { + const keys = Object.keys(storage); + return keys[i] || null; + } + }; +} else { + var localStorage = window.localStorage; +} + try { _solvedMap = JSON.parse( localStorage.getItem(SOLVED_MAP_STORAGE_KEY) || '{}' @@ -32,6 +56,26 @@ function _syncToStorage() { } } +function getAliasMap() { + try { + return JSON.parse(localStorage.getItem(ALIAS_STORAGE_KEY) || '{}') || {}; + } catch (e) { + return {}; + } +} + +function addToAliasMap(alias, expansion) { + const aliasMap = getAliasMap(); + aliasMap[alias] = expansion; + localStorage.setItem(ALIAS_STORAGE_KEY, JSON.stringify(aliasMap)); +} + +function removeFromAliasMap(alias) { + const aliasMap = getAliasMap(); + delete aliasMap[alias]; + localStorage.setItem(ALIAS_STORAGE_KEY, JSON.stringify(aliasMap)); +} + var validateLevel = function(level) { level = level || {}; var requiredFields = [ @@ -41,7 +85,7 @@ var validateLevel = function(level) { 'solutionCommand' ]; - _.each(requiredFields, function(field) { + requiredFields.forEach(function(field) { if (level[field] === undefined) { console.log(level); throw new Error('I need this field for a level: ' + field); @@ -52,18 +96,19 @@ var validateLevel = function(level) { /** * Unpack the level sequences. */ -_.each(levelSequences, function(levels, levelSequenceName) { +Object.keys(levelSequences).forEach(function(levelSequenceName) { + var levels = levelSequences[levelSequenceName]; _sequences.push(levelSequenceName); if (!levels || !levels.length) { throw new Error('no empty sequences allowed'); } // for this particular sequence... - _.each(levels, function(level, index) { + levels.forEach(function(level, index) { validateLevel(level); var id = levelSequenceName + String(index + 1); - var compiledLevel = assign( + var compiledLevel = Object.assign( {}, level, { @@ -79,17 +124,21 @@ _.each(levelSequences, function(levels, levelSequenceName) { }); }); -var LevelStore = assign( +var LevelStore = Object.assign( {}, EventEmitter.prototype, AppConstants.StoreSubscribePrototype, { + getAliasMap: getAliasMap, + addToAliasMap: addToAliasMap, + removeFromAliasMap: removeFromAliasMap, + getSequenceToLevels: function() { return levelSequences; }, getSequences: function() { - return _.keys(levelSequences); + return Object.keys(levelSequences); }, getLevelsInSequence: function(sequenceName) { @@ -109,11 +158,11 @@ AppConstants.StoreSubscribePrototype, getNextLevel: function(id) { if (!_levelMap[id]) { - console.warn('that level doesnt exist!!!'); + console.warn('that level doesn\'t exist!!!'); return null; } - // meh, this method could be better. It's a tradeoff between + // meh, this method could be better. It's a trade-off between // having the sequence structure be really simple JSON // and having no connectivity information between levels, which means // you have to build that up yourself on every query @@ -138,7 +187,7 @@ AppConstants.StoreSubscribePrototype, isLevelSolved: function(levelID) { if (!_levelMap[levelID]) { - throw new Error('that level doesnt exist!'); + throw new Error('that level doesn\'t exist!'); } return !!_solvedMap[levelID]; }, diff --git a/src/js/stores/LocaleStore.js b/src/js/stores/LocaleStore.js index 3b1a27b4..0e9d2601 100644 --- a/src/js/stores/LocaleStore.js +++ b/src/js/stores/LocaleStore.js @@ -2,10 +2,9 @@ var AppConstants = require('../constants/AppConstants'); var AppDispatcher = require('../dispatcher/AppDispatcher'); +var util = require('../util'); var EventEmitter = require('events').EventEmitter; -var assign = require('object-assign'); - var ActionTypes = AppConstants.ActionTypes; var DEFAULT_LOCALE = 'en_US'; @@ -21,15 +20,26 @@ var langLocaleMap = { de: 'de_DE', pt: 'pt_BR', ru: 'ru_RU', - uk: 'uk' + uk: 'uk', + vi: 'vi', + sl: 'sl_SI', + pl: 'pl', + ta: 'ta_IN' }; var headerLocaleMap = { 'zh-CN': 'zh_CN', 'zh-TW': 'zh_TW', - 'pt-BR': 'pt_BR' + 'pt-BR': 'pt_BR', + 'es-MX': 'es_MX', + 'es-ES': 'es_ES', + 'sl-SI': 'sl_SI' }; +var supportedLocalesList = Object.values(langLocaleMap) + .concat(Object.values(headerLocaleMap)) + .filter(function (value, index, self) { return self.indexOf(value) === index;}); + function _getLocaleFromHeader(langString) { var languages = langString.split(','); var desiredLocale; @@ -51,7 +61,7 @@ function _getLocaleFromHeader(langString) { } var _locale = DEFAULT_LOCALE; -var LocaleStore = assign( +var LocaleStore = Object.assign( {}, EventEmitter.prototype, AppConstants.StoreSubscribePrototype, @@ -62,20 +72,25 @@ AppConstants.StoreSubscribePrototype, }, getLangLocaleMap: function() { - return assign({}, langLocaleMap); + return Object.assign({}, langLocaleMap); }, getHeaderLocaleMap: function() { - return assign({}, headerLocaleMap); + return Object.assign({}, headerLocaleMap); }, getLocale: function() { return _locale; }, + getSupportedLocales: function() { + return supportedLocalesList.slice(); + }, + dispatchToken: AppDispatcher.register(function(payload) { var action = payload.action; var shouldInform = false; + var oldLocale = _locale; switch (action.type) { case ActionTypes.CHANGE_LOCALE: @@ -91,6 +106,12 @@ AppConstants.StoreSubscribePrototype, break; } + if (util.isBrowser() && oldLocale !== _locale) { + var url = new URL(document.location.href); + url.searchParams.set('locale', _locale); + window.history.replaceState({}, '', url.href); + } + if (shouldInform) { LocaleStore.emit(AppConstants.CHANGE_EVENT); } diff --git a/src/js/util/constants.js b/src/js/util/constants.js index ea581a88..7a3a52c4 100644 --- a/src/js/util/constants.js +++ b/src/js/util/constants.js @@ -44,7 +44,7 @@ var GRAPHICS = { tagFill: 'hsb(0,0,0.9)', tagStroke: '#FFF', tagStrokeWidth: '2', - + orphanNodeFill: 'hsb(0.5,0.8,0.7)' }; diff --git a/src/js/util/debounce.js b/src/js/util/debounce.js new file mode 100644 index 00000000..0f8bd3b4 --- /dev/null +++ b/src/js/util/debounce.js @@ -0,0 +1,17 @@ +module.exports = function(func, time, immediate) { + var timeout; + return function() { + var later = function() { + timeout = null; + if (!immediate) { + func.apply(this, arguments); + } + }; + var callNow = immediate && !timeout; + clearTimeout(timeout); + timeout = setTimeout(later, time); + if (callNow) { + func.apply(this, arguments); + } + }; + }; diff --git a/src/js/util/debug.js b/src/js/util/debug.js index a9359f1d..227e6113 100644 --- a/src/js/util/debug.js +++ b/src/js/util/debug.js @@ -30,7 +30,7 @@ var toGlobalize = { Level: require('../level'), Sandbox: require('../sandbox/'), GitDemonstrationView: require('../views/gitDemonstrationView'), - Markdown: require('markdown'), + Markdown: require('marked'), LevelDropdownView: require('../views/levelDropdownView'), BuilderViews: require('../views/builderViews'), Util: require('../util/index'), @@ -59,4 +59,3 @@ $(document).ready(function() { return toGlobalize.Main.getSandbox().mainVis.gitEngine.printAndCopyTree(); }; }); - diff --git a/src/js/util/eventBaton.js b/src/js/util/eventBaton.js index e6059d43..278a1475 100644 --- a/src/js/util/eventBaton.js +++ b/src/js/util/eventBaton.js @@ -27,7 +27,7 @@ EventBaton.prototype.sliceOffArgs = function(num, args) { }; EventBaton.prototype.trigger = function(name) { - // arguments is weird and doesnt do slice right + // arguments is weird and doesn't do slice right var argsToApply = this.sliceOffArgs(1, arguments); var listeners = this.eventMap[name]; @@ -76,7 +76,7 @@ EventBaton.prototype.passBatonBack = function(name, func, context, args) { } }); if (indexBefore === undefined) { - throw new Error('you are the last baton holder! or i didnt find you'); + throw new Error('you are the last baton holder! or i didn\'t find you'); } var toCallObj = listeners[indexBefore]; @@ -105,7 +105,7 @@ EventBaton.prototype.releaseBaton = function(name, func, context) { if (!found) { console.log('did not find that function', func, context, name, arguments); console.log(this.eventMap); - throw new Error('cant releasebaton if yu dont have it'); + throw new Error('can\'t releasebaton if you don\'t have it'); } this.eventMap[name] = newListeners; }; diff --git a/src/js/util/index.js b/src/js/util/index.js index ceab3013..84d7ffc2 100644 --- a/src/js/util/index.js +++ b/src/js/util/index.js @@ -1,3 +1,6 @@ +var { readdirSync, lstatSync } = require('fs'); +var { join } = require('path'); + var escapeString = require('../util/escapeString'); var constants = require('../util/constants'); @@ -24,7 +27,8 @@ exports.splitTextCommand = function(value, func, context) { .replace(/^(\s+)/, '') .replace(/(\s+)$/, '') .replace(/"/g, '"') - .replace(/'/g, "'"); + .replace(/'/g, "'") + .replace(///g, "/"); if (index > 0 && !command.length) { return; @@ -55,3 +59,16 @@ exports.genParseCommand = function(regexMap, eventName) { }; }; }; + +exports.readDirDeep = function(dir) { + var paths = []; + readdirSync(dir).forEach(function(path) { + var aPath = join(dir, path); + if (lstatSync(aPath).isDirectory()) { + paths.push(...exports.readDirDeep(aPath)); + } else { + paths.push(aPath); + } + }); + return paths; +}; diff --git a/src/js/util/throttle.js b/src/js/util/throttle.js new file mode 100644 index 00000000..58d11641 --- /dev/null +++ b/src/js/util/throttle.js @@ -0,0 +1,13 @@ +module.exports = function(func, time) { + var wait = false; + return function() { + if (!wait) { + func.apply(this, arguments); + wait = true; + + setTimeout(function() { + wait = false; + }, time); + } + }; + }; diff --git a/src/js/views/builderViews.js b/src/js/views/builderViews.js index bdf41b0e..c3931519 100644 --- a/src/js/views/builderViews.js +++ b/src/js/views/builderViews.js @@ -1,7 +1,9 @@ var _ = require('underscore'); var Q = require('q'); +var marked = require('marked'); var Views = require('../views'); +var throttle = require('../util/throttle'); var ModalTerminal = Views.ModalTerminal; var ContainedBase = Views.ContainedBase; @@ -97,7 +99,7 @@ var MarkdownGrabber = ContainedBase.extend({ keyup: function() { if (!this.throttledPreview) { - this.throttledPreview = _.throttle( + this.throttledPreview = throttle( this.updatePreview.bind(this), 500 ); @@ -121,7 +123,7 @@ var MarkdownGrabber = ContainedBase.extend({ updatePreview: function() { var raw = this.getRawText(); - var HTML = require('markdown').markdown.toHTML(raw); + var HTML = marked(raw); this.$('div.insidePreview').html(HTML); } }); @@ -179,7 +181,7 @@ var DemonstrationBuilder = ContainedBase.extend({ this.deferred = options.deferred || Q.defer(); if (options.fromObj) { var toEdit = options.fromObj.options; - options = _.extend( + options = Object.assign( {}, options, toEdit, @@ -295,7 +297,7 @@ var MultiViewBuilder = ContainedBase.extend({ this.JSON = { views: this.getChildViews(), - supportedViews: _.keys(this.typeToConstructor) + supportedViews: Object.keys(this.typeToConstructor) }; this.container = new ModalTerminal({ @@ -334,7 +336,7 @@ var MultiViewBuilder = ContainedBase.extend({ this.addChildViewObj(newView); }.bind(this)) .fail(function() { - // they dont want to add the view apparently, so just return + // they don't want to add the view apparently, so just return }) .done(); }, @@ -416,4 +418,3 @@ exports.DemonstrationBuilder = DemonstrationBuilder; exports.TextGrabber = TextGrabber; exports.MultiViewBuilder = MultiViewBuilder; exports.MarkdownPresenter = MarkdownPresenter; - diff --git a/src/js/views/commandViews.js b/src/js/views/commandViews.js index 63ebef01..b47d4bfa 100644 --- a/src/js/views/commandViews.js +++ b/src/js/views/commandViews.js @@ -1,4 +1,3 @@ -var _ = require('underscore'); var Backbone = require('backbone'); var Main = require('../app'); @@ -173,7 +172,7 @@ var CommandPromptView = Backbone.View.extend({ which.reverse(); var str = ''; - _.each(which, function(text) { + which.forEach(function(text) { str += text + ';'; }, this); @@ -202,4 +201,3 @@ var CommandPromptView = Backbone.View.extend({ }); exports.CommandPromptView = CommandPromptView; - diff --git a/src/js/views/gitDemonstrationView.js b/src/js/views/gitDemonstrationView.js index 498d1901..65a841e7 100644 --- a/src/js/views/gitDemonstrationView.js +++ b/src/js/views/gitDemonstrationView.js @@ -1,6 +1,7 @@ var _ = require('underscore'); var Q = require('q'); var Backbone = require('backbone'); +var marked = require('marked'); var util = require('../util'); var intl = require('../intl'); @@ -25,7 +26,7 @@ var GitDemonstrationView = ContainedBase.extend({ initialize: function(options) { options = options || {}; this.options = options; - this.JSON = _.extend( + this.JSON = Object.assign( { beforeMarkdowns: [ '## Git Commits', @@ -43,7 +44,7 @@ var GitDemonstrationView = ContainedBase.extend({ ); var convert = function(markdowns) { - return require('markdown').markdown.toHTML(markdowns.join('\n')); + return marked(markdowns.join('\n')); }; this.JSON.beforeHTML = convert(this.JSON.beforeMarkdowns); @@ -55,7 +56,7 @@ var GitDemonstrationView = ContainedBase.extend({ this.render(); this.checkScroll(); - this.navEvents = _.clone(Backbone.Events); + this.navEvents = Object.assign({}, Backbone.Events); this.navEvents.on('positive', this.positive, this); this.navEvents.on('negative', this.negative, this); this.keyboardListener = new KeyboardListener({ @@ -83,9 +84,9 @@ var GitDemonstrationView = ContainedBase.extend({ }, checkScroll: function() { - var children = this.$('div.demonstrationText').children(); - var heights = _.map(children, function(child) { return child.clientHeight; }); - var totalHeight = _.reduce(heights, function(a, b) { return a + b; }); + var children = this.$('div.demonstrationText').children().toArray(); + var heights = children.map(function(child) { return child.clientHeight; }); + var totalHeight = heights.reduce(function(a, b) { return a + b; }); if (totalHeight < this.$('div.demonstrationText').height()) { this.$('div.demonstrationText').addClass('noLongText'); } @@ -129,9 +130,9 @@ var GitDemonstrationView = ContainedBase.extend({ positive: function() { if (this.demonstrated || !this.hasControl) { - // dont do anything if we are demonstrating, and if + // don't do anything if we are demonstrating, and if // we receive a meta nav event and we aren't listening, - // then dont do anything either + // then don't do anything either return; } this.demonstrated = true; @@ -168,7 +169,7 @@ var GitDemonstrationView = ContainedBase.extend({ var chainDeferred = Q.defer(); var chainPromise = chainDeferred.promise; - _.each(commands, function(command, index) { + commands.forEach(function(command, index) { chainPromise = chainPromise.then(function() { var myDefer = Q.defer(); this.mainVis.gitEngine.dispatch(command, myDefer); @@ -244,4 +245,3 @@ var GitDemonstrationView = ContainedBase.extend({ }); exports.GitDemonstrationView = GitDemonstrationView; - diff --git a/src/js/views/index.js b/src/js/views/index.js index c44320fa..759a1658 100644 --- a/src/js/views/index.js +++ b/src/js/views/index.js @@ -1,12 +1,15 @@ var _ = require('underscore'); var Q = require('q'); var Backbone = require('backbone'); +var marked = require('marked'); var Main = require('../app'); var intl = require('../intl'); var log = require('../log'); var Constants = require('../util/constants'); var KeyboardListener = require('../util/keyboard').KeyboardListener; +var debounce = require('../util/debounce'); +var throttle = require('../util/throttle'); var BaseView = Backbone.View.extend({ getDestination: function() { @@ -86,7 +89,7 @@ var GeneralButton = ContainedBase.extend({ initialize: function(options) { options = options || {}; - this.navEvents = options.navEvents || _.clone(Backbone.Events); + this.navEvents = options.navEvents || Object.assign({}, Backbone.Events); this.destination = options.destination; if (!this.destination) { this.container = new ModalTerminal(); @@ -106,7 +109,7 @@ var GeneralButton = ContainedBase.extend({ click: function() { if (!this.clickFunc) { - this.clickFunc = _.throttle( + this.clickFunc = throttle( this.sendClick.bind(this), 500 ); @@ -136,8 +139,8 @@ var ConfirmCancelView = ResolveRejectBase.extend({ this.destination = options.destination; this.deferred = options.deferred || Q.defer(); this.JSON = { - confirm: options.confirm || 'Confirm', - cancel: options.cancel || 'Cancel' + confirm: options.confirm || intl.str('confirm-button'), + cancel: options.cancel || intl.str('cancel-button') }; this.render(); @@ -160,7 +163,7 @@ var LeftRightView = PositiveNegativeBase.extend({ // events system to add support for git demonstration view taking control of the // click events this.pipeEvents = options.events; - this.navEvents = _.clone(Backbone.Events); + this.navEvents = Object.assign({}, Backbone.Events); this.JSON = { showLeft: (options.showLeft === undefined) ? true : options.showLeft, @@ -168,7 +171,7 @@ var LeftRightView = PositiveNegativeBase.extend({ }; this.render(); - // For some weird reason backbone events arent working anymore so + // For some weird reason backbone events aren't working anymore so // im going to just wire this up manually this.$('div.right').click(this.positive.bind(this)); this.$('div.left').click(this.negative.bind(this)); @@ -208,7 +211,7 @@ var ModalView = Backbone.View.extend({ // add ourselves to the DOM this.$el.html(this.template({})); $('body').append(this.el); - // this doesnt necessarily show us though... + // this doesn't necessarily show us though... }, stealKeyboard: function() { @@ -305,11 +308,11 @@ var ModalTerminal = ContainedBase.extend({ initialize: function(options) { options = options || {}; - this.navEvents = options.events || _.clone(Backbone.Events); + this.navEvents = options.events || Object.assign({}, Backbone.Events); this.container = new ModalView(); this.JSON = { - title: options.title + title: options.title }; this.render(); @@ -354,7 +357,7 @@ var ModalAlert = ContainedBase.extend({ render: function() { var HTML = (this.JSON.markdown) ? - require('markdown').markdown.toHTML(this.JSON.markdown) : + marked(this.JSON.markdown) : this.template(this.JSON); // one more hack -- allow adding custom random HTML if specified if (this.options._dangerouslyInsertHTML) { @@ -372,7 +375,7 @@ var ConfirmCancelTerminal = Backbone.View.extend({ options = options || {}; this.deferred = options.deferred || Q.defer(); - this.modalAlert = new ModalAlert(_.extend( + this.modalAlert = new ModalAlert(Object.assign( {}, { markdown: '#you sure?' }, options @@ -395,7 +398,7 @@ var ConfirmCancelTerminal = Backbone.View.extend({ }.bind(this)); // also setup keyboard - this.navEvents = _.clone(Backbone.Events); + this.navEvents = Object.assign({}, Backbone.Events); this.navEvents.on('positive', this.positive, this); this.navEvents.on('negative', this.negative, this); this.keyboardListener = new KeyboardListener({ @@ -470,7 +473,7 @@ var NextLevelConfirm = ConfirmCancelTerminal.extend({ '

'; } - options = _.extend( + options = Object.assign( {}, options, { @@ -580,7 +583,7 @@ var CanvasTerminalHolder = BaseView.extend({ // If the entire window gets resized such that the terminal is outside the view, then // move it back into the view, and expand/shrink it vertically as necessary. - $(window).on('resize', _.debounce(this.recalcLayout.bind(this), 300)); + $(window).on('resize', debounce(this.recalcLayout.bind(this), 300)); if (options.additionalClass) { this.$el.addClass(options.additionalClass); diff --git a/src/js/views/levelDropdownView.js b/src/js/views/levelDropdownView.js index 79858ed0..a5e9adbe 100644 --- a/src/js/views/levelDropdownView.js +++ b/src/js/views/levelDropdownView.js @@ -4,6 +4,7 @@ var Backbone = require('backbone'); var LocaleStore = require('../stores/LocaleStore'); var util = require('../util'); +var debounce = require('../util/debounce'); var intl = require('../intl'); var log = require('../log'); var KeyboardListener = require('../util/keyboard').KeyboardListener; @@ -40,8 +41,8 @@ var LevelDropdownView = ContainedBase.extend({ }] }; - this.navEvents = _.clone(Backbone.Events); - this.navEvents.on('clickedID', _.debounce( + this.navEvents = Object.assign({}, Backbone.Events); + this.navEvents.on('clickedID', debounce( this.loadLevelID.bind(this), 300, true @@ -211,7 +212,7 @@ var LevelDropdownView = ContainedBase.extend({ }, getTabIndex: function() { - var ids = _.map(this.JSON.tabs, function(tab) { + var ids = this.JSON.tabs.map(function(tab) { return tab.id; }); return ids.indexOf(this.JSON.selectedTab); @@ -235,7 +236,7 @@ var LevelDropdownView = ContainedBase.extend({ }, getSequencesOnTab: function() { - return _.filter(this.sequences, function(sequenceName) { + return this.sequences.filter(function(sequenceName) { var tab = LEVELS.getTabForSequence(sequenceName); return tab === this.JSON.selectedTab; }, this); @@ -292,7 +293,7 @@ var LevelDropdownView = ContainedBase.extend({ $(selector).toggleClass('selected', value); // also go find the series and update the about - _.each(this.seriesViews, function(view) { + this.seriesViews.forEach(function(view) { if (view.levelIDs.indexOf(id) === -1) { return; } @@ -343,14 +344,14 @@ var LevelDropdownView = ContainedBase.extend({ }, updateSolvedStatus: function() { - _.each(this.seriesViews, function(view) { + this.seriesViews.forEach(function(view) { view.updateSolvedStatus(); }, this); }, buildSequences: function() { this.seriesViews = []; - _.each(this.getSequencesOnTab(), function(sequenceName) { + this.getSequencesOnTab().forEach(function(sequenceName) { this.seriesViews.push(new SeriesView({ destination: this.$el, name: sequenceName, @@ -377,7 +378,7 @@ var SeriesView = BaseView.extend({ this.levelIDs = []; var firstLevelInfo = null; - _.each(this.levels, function(level) { + this.levels.forEach(function(level) { if (firstLevelInfo === null) { firstLevelInfo = this.formatLevelAbout(level.id); } @@ -444,4 +445,3 @@ var SeriesView = BaseView.extend({ }); exports.LevelDropdownView = LevelDropdownView; - diff --git a/src/js/views/multiView.js b/src/js/views/multiView.js index 79ec192b..7d44a39a 100644 --- a/src/js/views/multiView.js +++ b/src/js/views/multiView.js @@ -1,4 +1,3 @@ -var _ = require('underscore'); var Q = require('q'); var Backbone = require('backbone'); @@ -10,6 +9,7 @@ var BuilderViews = require('../views/builderViews'); var MarkdownPresenter = BuilderViews.MarkdownPresenter; var KeyboardListener = require('../util/keyboard').KeyboardListener; +var debounce = require('../util/debounce'); var MultiView = Backbone.View.extend({ tagName: 'div', @@ -48,7 +48,7 @@ var MultiView = Backbone.View.extend({ this.childViews = []; this.currentIndex = 0; - this.navEvents = _.clone(Backbone.Events); + this.navEvents = Object.assign({}, Backbone.Events); this.navEvents.on('negative', this.getNegFunc(), this); this.navEvents.on('positive', this.getPosFunc(), this); this.navEvents.on('quit', this.finish, this); @@ -84,13 +84,13 @@ var MultiView = Backbone.View.extend({ }, getPosFunc: function() { - return _.debounce(function() { + return debounce(function() { this.navForward(); }.bind(this), this.navEventDebounce, true); }, getNegFunc: function() { - return _.debounce(function() { + return debounce(function() { this.navBackward(); }.bind(this), this.navEventDebounce, true); }, @@ -142,7 +142,7 @@ var MultiView = Backbone.View.extend({ // other views will take if they need to this.keyboardListener.mute(); - _.each(this.childViews, function(childView) { + this.childViews.forEach(function(childView) { childView.die(); }); @@ -159,7 +159,7 @@ var MultiView = Backbone.View.extend({ if (!this.typeToConstructor[type]) { throw new Error('no constructor for type "' + type + '"'); } - var view = new this.typeToConstructor[type](_.extend( + var view = new this.typeToConstructor[type](Object.assign( {}, viewJSON.options, { wait: true } @@ -183,7 +183,7 @@ var MultiView = Backbone.View.extend({ render: function() { // go through each and render... show the first - _.each(this.childViewJSONs, function(childViewJSON, index) { + this.childViewJSONs.forEach(function(childViewJSON, index) { var childView = this.createChildView(childViewJSON); this.childViews.push(childView); this.addNavToView(childView, index); @@ -192,4 +192,3 @@ var MultiView = Backbone.View.extend({ }); exports.MultiView = MultiView; - diff --git a/src/js/views/rebaseView.js b/src/js/views/rebaseView.js index ed19ca8f..3bd3a3c7 100644 --- a/src/js/views/rebaseView.js +++ b/src/js/views/rebaseView.js @@ -7,6 +7,17 @@ var ModalTerminal = require('../views').ModalTerminal; var ContainedBase = require('../views').ContainedBase; var ConfirmCancelView = require('../views').ConfirmCancelView; +require('jquery-ui/ui/widget'); +require('jquery-ui/ui/scroll-parent'); +require('jquery-ui/ui/data'); +require('jquery-ui/ui/widgets/mouse'); +require('jquery-ui/ui/ie'); +require('jquery-ui/ui/widgets/sortable'); +require('jquery-ui/ui/plugin'); +require('jquery-ui/ui/safe-active-element'); +require('jquery-ui/ui/safe-blur'); +require('jquery-ui/ui/widgets/draggable'); + var InteractiveRebaseView = ContainedBase.extend({ tagName: 'div', template: _.template($('#interactive-rebase-template').html()), @@ -19,7 +30,7 @@ var InteractiveRebaseView = ContainedBase.extend({ this.rebaseEntries = new RebaseEntryCollection(); options.toRebase.reverse(); - _.each(options.toRebase, function(commit) { + options.toRebase.forEach(function(commit) { var id = commit.get('id'); this.rebaseMap[id] = commit; @@ -63,7 +74,7 @@ var InteractiveRebaseView = ContainedBase.extend({ // now get the real array var toRebase = []; - _.each(uiOrder, function(id) { + uiOrder.forEach(function(id) { // the model pick check if (this.entryObjMap[id].get('pick')) { toRebase.unshift(this.rebaseMap[id]); @@ -78,7 +89,7 @@ var InteractiveRebaseView = ContainedBase.extend({ render: function() { var json = { - num: _.keys(this.rebaseMap).length, + num: Object.keys(this.rebaseMap).length, solutionOrder: this.options.initialCommitOrdering }; @@ -164,7 +175,6 @@ var RebaseEntryView = Backbone.View.extend({ }, render: function() { - var json = this.model.toJSON(); this.$el.append(this.template(this.model.toJSON())); // hacky :( who would have known jquery barfs on ids with %'s and quotes diff --git a/src/js/visuals/animation/index.js b/src/js/visuals/animation/index.js index cd0784c4..1fa30291 100644 --- a/src/js/visuals/animation/index.js +++ b/src/js/visuals/animation/index.js @@ -55,7 +55,7 @@ var AnimationQueue = Backbone.Model.extend({ }, add: function(animation) { - if (!animation instanceof Animation) { + if (!(animation instanceof Animation)) { throw new Error("Need animation not something else"); } diff --git a/src/js/visuals/index.js b/src/js/visuals/index.js index 70678ff3..54797c83 100644 --- a/src/js/visuals/index.js +++ b/src/js/visuals/index.js @@ -1,8 +1,8 @@ -var _ = require('underscore'); var Q = require('q'); var intl = require('../intl'); var GRAPHICS = require('../util/constants').GRAPHICS; +var debounce = require('../util/debounce'); var GlobalStateStore = require('../stores/GlobalStateStore'); var VisNode = require('../visuals/visNode').VisNode; @@ -58,7 +58,7 @@ GitVisuals.prototype.defer = function(action) { }; GitVisuals.prototype.deferFlush = function() { - _.each(this.deferred, function(action) { + this.deferred.forEach(function(action) { action(); }, this); this.deferred = []; @@ -68,21 +68,21 @@ GitVisuals.prototype.resetAll = function() { // make sure to copy these collections because we remove // items in place and underscore is too dumb to detect length change var edges = this.visEdgeCollection.toArray(); - _.each(edges, function(visEdge) { + edges.forEach(function(visEdge) { visEdge.remove(); }, this); var branches = this.visBranchCollection.toArray(); - _.each(branches, function(visBranch) { + branches.forEach(function(visBranch) { visBranch.remove(); }, this); var tags = this.visTagCollection.toArray(); - _.each(tags, function(visTag) { + tags.forEach(function(visTag) { visTag.remove(); }, this); - _.each(this.visNodeMap, function(visNode) { + Object.values(this.visNodeMap).forEach(function(visNode) { visNode.remove(); }, this); @@ -98,7 +98,7 @@ GitVisuals.prototype.resetAll = function() { GitVisuals.prototype.tearDown = function() { this.resetAll(); this.paper.remove(); - // Unregister the refresh tree listener so we dont accumulate + // Unregister the refresh tree listener so we don't accumulate // these over time. However we aren't calling tearDown in // some places... but this is an improvement var Main = require('../app'); @@ -206,7 +206,7 @@ GitVisuals.prototype.animateAllAttrKeys = function(keys, attr, speed, easing) { this.visBranchCollection.each(animate); this.visEdgeCollection.each(animate); this.visTagCollection.each(animate); - _.each(this.visNodeMap, animate); + Object.values(this.visNodeMap).forEach(animate); var time = (speed !== undefined) ? speed : GRAPHICS.defaultAnimationTime; setTimeout(function() { @@ -240,7 +240,7 @@ GitVisuals.prototype.finishAnimation = function(speed) { opacity: 0, 'font-weight': 500, 'font-size': '32pt', - 'font-family': 'Monaco, Courier, font-monospace', + 'font-family': 'Menlo, Monaco, Consolas, \'Droid Sans Mono\', monospace', stroke: '#000', 'stroke-width': 2, fill: '#000' @@ -321,7 +321,7 @@ GitVisuals.prototype.finishAnimation = function(speed) { GitVisuals.prototype.explodeNodes = function(speed) { var deferred = Q.defer(); var funcs = []; - _.each(this.visNodeMap, function(visNode) { + Object.values(this.visNodeMap).forEach(function(visNode) { funcs.push(visNode.getExplodeStepFunc(speed)); }); @@ -332,7 +332,7 @@ GitVisuals.prototype.explodeNodes = function(speed) { // are called unnecessarily when they have almost // zero speed. would be interesting to see performance differences var keepGoing = []; - _.each(funcs, function(func) { + funcs.forEach(function(func) { if (func()) { keepGoing.push(func); } @@ -354,12 +354,12 @@ GitVisuals.prototype.explodeNodes = function(speed) { GitVisuals.prototype.animateAllFromAttrToAttr = function(fromSnapshot, toSnapshot, idsToOmit) { var animate = function(obj) { var id = obj.getID(); - if (_.include(idsToOmit, id)) { + if (idsToOmit.includes(id)) { return; } if (!fromSnapshot[id] || !toSnapshot[id]) { - // its actually ok it doesnt exist yet + // its actually ok it doesn't exist yet return; } obj.animateFromAttrToAttr(fromSnapshot[id], toSnapshot[id]); @@ -368,7 +368,7 @@ GitVisuals.prototype.animateAllFromAttrToAttr = function(fromSnapshot, toSnapsho this.visBranchCollection.each(animate); this.visEdgeCollection.each(animate); this.visTagCollection.each(animate); - _.each(this.visNodeMap, animate); + Object.values(this.visNodeMap).forEach(animate); }; /*************************************** @@ -392,7 +392,7 @@ GitVisuals.prototype.genSnapshot = function() { this.fullCalc(); var snapshot = {}; - _.each(this.visNodeMap, function(visNode) { + Object.values(this.visNodeMap).forEach(function(visNode) { snapshot[visNode.get('id')] = visNode.getAttributes(); }, this); @@ -442,7 +442,7 @@ GitVisuals.prototype.fullCalc = function() { }; GitVisuals.prototype.calcTreeCoords = function() { - // this method can only contain things that dont rely on graphics + // this method can only contain things that don't rely on graphics if (!this.rootCommit) { throw new Error('grr, no root commit!'); } @@ -477,7 +477,7 @@ GitVisuals.prototype.getCommitUpstreamBranches = function(commit) { GitVisuals.prototype.getBlendedHuesForCommit = function(commit) { var branches = this.upstreamBranchSet[commit.get('id')]; if (!branches) { - throw new Error('that commit doesnt have upstream branches!'); + throw new Error('that commit doesn\'t have upstream branches!'); } return this.blendHuesFromBranchStack(branches); @@ -485,7 +485,7 @@ GitVisuals.prototype.getBlendedHuesForCommit = function(commit) { GitVisuals.prototype.blendHuesFromBranchStack = function(branchStackArray) { var hueStrings = []; - _.each(branchStackArray, function(branchWrapper) { + branchStackArray.forEach(function(branchWrapper) { var fill = branchWrapper.obj.get('visBranch').get('fill'); if (fill.slice(0,3) !== 'hsb') { @@ -525,7 +525,7 @@ GitVisuals.prototype.getCommitUpstreamStatus = function(commit) { GitVisuals.prototype.calcTagStacks = function() { var tags = this.gitEngine.getTags(); var map = {}; - _.each(tags, function(tag) { + tags.forEach(function(tag) { var thisId = tag.target.get('id'); map[thisId] = map[thisId] || []; @@ -542,7 +542,7 @@ GitVisuals.prototype.calcTagStacks = function() { GitVisuals.prototype.calcBranchStacks = function() { var branches = this.gitEngine.getBranches(); var map = {}; - _.each(branches, function(branch) { + branches.forEach(function(branch) { var thisId = branch.target.get('id'); map[thisId] = map[thisId] || []; @@ -572,7 +572,7 @@ GitVisuals.prototype.calcWidth = function() { GitVisuals.prototype.maxWidthRecursive = function(commit) { var childrenTotalWidth = 0; - _.each(commit.get('children'), function(child) { + commit.get('children').forEach(function(child) { // only include this if we are the "main" parent of // this child if (child.isMainParent(commit)) { @@ -601,14 +601,14 @@ GitVisuals.prototype.assignBoundsRecursive = function(commit, min, max) { // basic box-flex model var totalFlex = 0; var children = commit.get('children'); - _.each(children, function(child) { + children.forEach(function(child) { if (child.isMainParent(commit)) { totalFlex += child.get('visNode').getMaxWidthScaled(); } }, this); var prevBound = min; - _.each(children, function(child, index) { + children.forEach(function(child, index) { if (!child.isMainParent(commit)) { return; } @@ -632,7 +632,7 @@ GitVisuals.prototype.calcDepth = function() { } var depthIncrement = this.getDepthIncrement(maxDepth); - _.each(this.visNodeMap, function(visNode) { + Object.values(this.visNodeMap).forEach(function(visNode) { visNode.setDepthBasedOn(depthIncrement, this.getHeaderOffset()); }, this); }; @@ -655,7 +655,7 @@ GitVisuals.prototype.calcDepth = function() { **************************************/ GitVisuals.prototype.animateNodePositions = function(speed) { - _.each(this.visNodeMap, function(visNode) { + Object.values(this.visNodeMap).forEach(function(visNode) { visNode.animateUpdatedPosition(speed); }, this); }; @@ -701,6 +701,25 @@ GitVisuals.prototype.addTagFromEvent = function(tag, collection, index) { } }; +GitVisuals.prototype.removeTag = function(tag, collection, index) { + var action = function() { + var tagToRemove; + this.visTagCollection.each(function(visTag) { + if(visTag.get('tag') == tag){ + tagToRemove = visTag; + } + }, true); + tagToRemove.remove(); + this.removeVisTag(tagToRemove); + }.bind(this); + + if (!this.gitEngine || !this.gitReady) { + this.defer(action); + } else { + action(); + } +}; + GitVisuals.prototype.addTag = function(tag) { var visTag = new VisTag({ tag: tag, @@ -777,7 +796,7 @@ GitVisuals.prototype.calcDepthRecursive = function(commit, depth) { var children = commit.get('children'); var maxDepth = depth; - _.each(children, function(child) { + children.forEach(function(child) { var d = this.calcDepthRecursive(child, depth + 1); maxDepth = Math.max(d, maxDepth); }, this); @@ -795,7 +814,7 @@ GitVisuals.prototype.canvasResize = function(width, height) { }; GitVisuals.prototype.genResizeFunc = function() { - this.resizeFunc = _.debounce( + this.resizeFunc = debounce( function(width, height) { this.refreshTree(); }.bind(this), @@ -853,7 +872,7 @@ GitVisuals.prototype.zIndexReflow = function() { }; GitVisuals.prototype.visNodesFront = function() { - _.each(this.visNodeMap, function(visNode) { + Object.values(this.visNodeMap).forEach(function(visNode) { visNode.toFront(); }); }; @@ -892,7 +911,7 @@ GitVisuals.prototype.drawTreeFirstTime = function() { this.gitReady = true; this.calcTreeCoords(); - _.each(this.visNodeMap, function(visNode) { + Object.values(this.visNodeMap).forEach(function(visNode) { visNode.genGraphics(this.paper); }, this); @@ -924,7 +943,7 @@ function blendHueStrings(hueStrings) { var totalBright = 0; var length = hueStrings.length; - _.each(hueStrings, function(hueString) { + hueStrings.forEach(function(hueString) { var exploded = hueString.split('(')[1]; exploded = exploded.split(')')[0]; exploded = exploded.split(','); diff --git a/src/js/visuals/tree.js b/src/js/visuals/tree.js index e5952228..ad270a60 100644 --- a/src/js/visuals/tree.js +++ b/src/js/visuals/tree.js @@ -1,9 +1,8 @@ -var _ = require('underscore'); var Backbone = require('backbone'); var VisBase = Backbone.Model.extend({ removeKeys: function(keys) { - _.each(keys, function(key) { + keys.forEach(function(key) { if (this.get(key)) { this.get(key).remove(); } @@ -13,7 +12,7 @@ var VisBase = Backbone.Model.extend({ animateAttrKeys: function(keys, attrObj, speed, easing) { // either we animate a specific subset of keys or all // possible things we could animate - keys = _.extend( + keys = Object.assign( {}, { include: ['circle', 'arrow', 'rect', 'path', 'text'], @@ -25,15 +24,15 @@ var VisBase = Backbone.Model.extend({ var attr = this.getAttributes(); // safely insert this attribute into all the keys we want - _.each(keys.include, function(key) { - attr[key] = _.extend( + keys.include.forEach(function(key) { + attr[key] = Object.assign( {}, attr[key], attrObj ); }); - _.each(keys.exclude, function(key) { + keys.exclude.forEach(function(key) { delete attr[key]; }); @@ -42,4 +41,3 @@ var VisBase = Backbone.Model.extend({ }); exports.VisBase = VisBase; - diff --git a/src/js/visuals/visBase.js b/src/js/visuals/visBase.js index 7f06e6aa..fb6a68a1 100644 --- a/src/js/visuals/visBase.js +++ b/src/js/visuals/visBase.js @@ -1,9 +1,8 @@ -var _ = require('underscore'); var Backbone = require('backbone'); var VisBase = Backbone.Model.extend({ removeKeys: function(keys) { - _.each(keys, function(key) { + keys.forEach(function(key) { if (this.get(key)) { this.get(key).remove(); } @@ -35,14 +34,14 @@ var VisBase = Backbone.Model.extend({ }, setAttrBase: function(keys, attr, instant, speed, easing) { - _.each(keys, function(key) { + keys.forEach(function(key) { if (instant) { this.get(key).attr(attr[key]); } else { this.get(key).stop(); this.get(key).animate(attr[key], speed, easing); - // some keys dont support animating too, so set those instantly here - _.forEach(this.getNonAnimateKeys(), function(nonAnimateKey) { + // some keys don't support animating too, so set those instantly here + this.getNonAnimateKeys().forEach(function(nonAnimateKey) { if (attr[key] && attr[key][nonAnimateKey] !== undefined) { this.get(key).attr(nonAnimateKey, attr[key][nonAnimateKey]); } @@ -58,7 +57,7 @@ var VisBase = Backbone.Model.extend({ animateAttrKeys: function(keys, attrObj, speed, easing) { // either we animate a specific subset of keys or all // possible things we could animate - keys = _.extend( + keys = Object.assign( {}, { include: ['circle', 'arrow', 'rect', 'path', 'text'], @@ -70,15 +69,15 @@ var VisBase = Backbone.Model.extend({ var attr = this.getAttributes(); // safely insert this attribute into all the keys we want - _.each(keys.include, function(key) { - attr[key] = _.extend( + keys.include.forEach(function(key) { + attr[key] = Object.assign( {}, attr[key], attrObj ); }); - _.each(keys.exclude, function(key) { + keys.exclude.forEach(function(key) { delete attr[key]; }); @@ -87,4 +86,3 @@ var VisBase = Backbone.Model.extend({ }); exports.VisBase = VisBase; - diff --git a/src/js/visuals/visBranch.js b/src/js/visuals/visBranch.js index a492edc8..1294d54c 100644 --- a/src/js/visuals/visBranch.js +++ b/src/js/visuals/visBranch.js @@ -1,4 +1,3 @@ -var _ = require('underscore'); var Backbone = require('backbone'); var GRAPHICS = require('../util/constants').GRAPHICS; @@ -167,7 +166,7 @@ var VisBranch = VisBase.extend({ var myArray = this.getBranchStackArray(); var index = -1; - _.each(myArray, function(branch, i) { + myArray.forEach(function(branch, i) { if (branch.obj == this.get('branch')) { index = i; } @@ -279,7 +278,7 @@ var VisBranch = VisBase.extend({ arrowInnerLow, arrowStartLow ]; - _.each(coords, function(pos) { + coords.forEach(function(pos) { pathStr += 'L' + toStringCoords(pos) + ' '; }, this); pathStr += 'z'; @@ -309,7 +308,7 @@ var VisBranch = VisBase.extend({ } var maxWidth = 0; - _.each(this.getBranchStackArray(), function(branch) { + this.getBranchStackArray().forEach(function(branch) { maxWidth = Math.max(maxWidth, getTextWidth( branch.obj.get('visBranch') )); @@ -358,6 +357,9 @@ var VisBranch = VisBase.extend({ if (name === 'HEAD' && isHg) { name = '.'; } + if (name.match(/\bmaster\b/)) { + name = name.replace(/\bmaster\b/, 'main'); + } var after = (selected && !this.getIsInOrigin() && !isRemote) ? '*' : ''; return name + after; @@ -407,11 +409,11 @@ var VisBranch = VisBase.extend({ var textPos = this.getTextPosition(); var name = this.getName(); - // when from a reload, we dont need to generate the text + // when from a reload, we don't need to generate the text var text = paper.text(textPos.x, textPos.y, String(name)); text.attr({ 'font-size': 14, - 'font-family': 'Monaco, Courier, font-monospace', + 'font-family': 'Menlo, Monaco, Consolas, \'Droid Sans Mono\', monospace', opacity: this.getTextOpacity() }); this.set('text', text); @@ -432,7 +434,7 @@ var VisBranch = VisBase.extend({ // set CSS var keys = ['text', 'rect', 'arrow']; - _.each(keys, function(key) { + keys.forEach(function(key) { $(this.get(key).node).css(attr.css); }, this); @@ -451,7 +453,7 @@ var VisBranch = VisBase.extend({ this.get('arrow') ]; - _.each(objs, function(rObj) { + objs.forEach(function(rObj) { rObj.click(this.onClick.bind(this)); }, this); }, @@ -577,4 +579,3 @@ var VisBranchCollection = Backbone.Collection.extend({ exports.VisBranchCollection = VisBranchCollection; exports.VisBranch = VisBranch; exports.randomHueString = randomHueString; - diff --git a/src/js/visuals/visEdge.js b/src/js/visuals/visEdge.js index b47ef8de..355efcf4 100644 --- a/src/js/visuals/visEdge.js +++ b/src/js/visuals/visEdge.js @@ -1,4 +1,3 @@ -var _ = require('underscore'); var Backbone = require('backbone'); var GRAPHICS = require('../util/constants').GRAPHICS; @@ -15,7 +14,7 @@ var VisEdge = VisBase.extend({ validateAtInit: function() { var required = ['tail', 'head']; - _.each(required, function(key) { + required.forEach(function(key) { if (!this.get(key)) { throw new Error(key + ' is required!'); } diff --git a/src/js/visuals/visNode.js b/src/js/visuals/visNode.js index 1cb08d86..a3a50612 100644 --- a/src/js/visuals/visNode.js +++ b/src/js/visuals/visNode.js @@ -1,4 +1,3 @@ -var _ = require('underscore'); var Backbone = require('backbone'); var GRAPHICS = require('../util/constants').GRAPHICS; @@ -261,33 +260,33 @@ var VisNode = VisBase.extend({ }, setOutgoingEdgesOpacity: function(opacity) { - _.each(this.get('outgoingEdges'), function(edge) { + this.get('outgoingEdges').forEach(function(edge) { edge.setOpacity(opacity); }); }, animateOutgoingEdgesToAttr: function(snapShot, speed, easing) { - _.each(this.get('outgoingEdges'), function(edge) { + this.get('outgoingEdges').forEach(function(edge) { var attr = snapShot[edge.getID()]; edge.animateToAttr(attr); }, this); }, animateOutgoingEdges: function(speed, easing) { - _.each(this.get('outgoingEdges'), function(edge) { + this.get('outgoingEdges').forEach(function(edge) { edge.animateUpdatedPath(speed, easing); }, this); }, animateOutgoingEdgesFromSnapshot: function(snapshot, speed, easing) { - _.each(this.get('outgoingEdges'), function(edge) { + this.get('outgoingEdges').forEach(function(edge) { var attr = snapshot[edge.getID()]; edge.animateToAttr(attr, speed, easing); }, this); }, setOutgoingEdgesBirthPosition: function(parentCoords) { - _.each(this.get('outgoingEdges'), function(edge) { + this.get('outgoingEdges').forEach(function(edge) { var headPos = edge.get('head').getScreenCoords(); var path = edge.genSmoothBezierPathStringFromCoords(parentCoords, headPos); edge.get('path').stop(); @@ -334,7 +333,7 @@ var VisNode = VisBase.extend({ } var commandStr = 'git checkout ' + this.get('commit').get('id'); var Main = require('../app'); - _.each([this.get('circle'), this.get('text')], function(rObj) { + [this.get('circle'), this.get('text')].forEach(function(rObj) { rObj.click(function() { Main.getEventBaton().trigger('commandSubmitted', commandStr); }); @@ -347,7 +346,7 @@ var VisNode = VisBase.extend({ // set the opacity on my stuff var keys = ['circle', 'text']; - _.each(keys, function(key) { + keys.forEach(function(key) { this.get(key).attr({ opacity: opacity }); @@ -371,7 +370,7 @@ var VisNode = VisBase.extend({ }, removeAllEdges: function() { - _.each(this.get('outgoingEdges'), function(edge) { + this.get('outgoingEdges').forEach(function(edge) { edge.remove(); }, this); }, @@ -421,7 +420,7 @@ var VisNode = VisBase.extend({ }); // continuation calculation if ((vx * vx + vy * vy) < 0.1 && Math.abs(y - maxHeight) <= 0.1) { - // dont need to animate anymore, we are on ground + // don't need to animate anymore, we are on ground return false; } // keep animating! @@ -452,7 +451,7 @@ var VisNode = VisBase.extend({ text.attr({ 'font-size': this.getFontSize(this.get('id')), 'font-weight': 'bold', - 'font-family': 'Monaco, Courier, font-monospace', + 'font-family': 'Menlo, Monaco, Consolas, \'Droid Sans Mono\', monospace', opacity: this.getOpacity() }); diff --git a/src/js/visuals/visTag.js b/src/js/visuals/visTag.js index f7ce663c..2f8d4650 100644 --- a/src/js/visuals/visTag.js +++ b/src/js/visuals/visTag.js @@ -1,4 +1,3 @@ -var _ = require('underscore'); var Backbone = require('backbone'); var GRAPHICS = require('../util/constants').GRAPHICS; @@ -95,7 +94,7 @@ var VisTag = VisBase.extend({ var myArray = this.getTagStackArray(); var index = -1; - _.each(myArray, function(Tag, i) { + myArray.forEach(function(Tag, i) { if (Tag.obj == this.get('tag')) { index = i; } @@ -175,7 +174,7 @@ var VisTag = VisBase.extend({ var textNode = this.get('text').node; var maxWidth = 0; - _.each(this.getTagStackArray(), function(Tag) { + this.getTagStackArray().forEach(function(Tag) { maxWidth = Math.max(maxWidth, getTextWidth( Tag.obj.get('visTag') )); @@ -251,11 +250,11 @@ var VisTag = VisBase.extend({ var textPos = this.getTextPosition(); var name = this.getName(); - // when from a reload, we dont need to generate the text + // when from a reload, we don't need to generate the text var text = paper.text(textPos.x, textPos.y, String(name)); text.attr({ 'font-size': 14, - 'font-family': 'Monaco, Courier, font-monospace', + 'font-family': 'Menlo, Monaco, Consolas, \'Droid Sans Mono\', monospace', opacity: this.getTextOpacity(), 'text-anchor': 'start' }); @@ -271,7 +270,7 @@ var VisTag = VisBase.extend({ // set CSS var keys = ['text', 'rect']; - _.each(keys, function(key) { + keys.forEach(function(key) { $(this.get(key).node).css(attr.css); }, this); @@ -289,7 +288,7 @@ var VisTag = VisBase.extend({ this.get('text') ]; - _.each(objs, function(rObj) { + objs.forEach(function(rObj) { rObj.click(this.onClick.bind(this)); }, this); }, @@ -405,4 +404,3 @@ var VisTagCollection = Backbone.Collection.extend({ exports.VisTagCollection = VisTagCollection; exports.VisTag = VisTag; exports.randomHueString = randomHueString; - diff --git a/src/js/visuals/visualization.js b/src/js/visuals/visualization.js index 7c9ebb97..44bc4b0d 100644 --- a/src/js/visuals/visualization.js +++ b/src/js/visuals/visualization.js @@ -1,4 +1,3 @@ -var _ = require('underscore'); var Backbone = require('backbone'); var Collections = require('../models/collections'); @@ -13,7 +12,7 @@ var Visualization = Backbone.View.extend({ initialize: function(options) { options = options || {}; this.options = options; - this.customEvents = _.clone(Backbone.Events); + this.customEvents = Object.assign({}, Backbone.Events); this.containerElement = options.containerElement; var _this = this; @@ -34,7 +33,7 @@ var Visualization = Backbone.View.extend({ this.paper = paper; var Main = require('../app'); - // if we dont want to receive keyboard input (directly), + // if we don't want to receive keyboard input (directly), // make a new event baton so git engine steals something that no one // is broadcasting to this.eventBaton = (options.noKeyboardInput) ? @@ -69,9 +68,7 @@ var Visualization = Backbone.View.extend({ this.myResize(); - $(window).on('resize', function() { - this.myResize(); - }.bind(this)); + $(window).on('resize', () => this.myResize()); // If the visualization is within a draggable container, we need to update the // position whenever the container is moved. @@ -104,7 +101,7 @@ var Visualization = Backbone.View.extend({ makeOrigin: function(options) { // oh god, here we go. We basically do a bizarre form of composition here, // where this visualization actually contains another one of itself. - this.originVis = new Visualization(_.extend( + this.originVis = new Visualization(Object.assign( {}, // copy all of our options over, except... this.options, @@ -258,12 +255,11 @@ var Visualization = Backbone.View.extend({ myResize: function() { if (!this.paper) { return; } - var smaller = 1; var el = this.el; var elSize = el.getBoundingClientRect(); - var width = elSize.width - smaller; - var height = elSize.height - smaller; + var width = elSize.width; + var height = elSize.height; // if we don't have a container, we need to set our // position absolutely to whatever we are tracking diff --git a/src/levels/advanced/multipleParents.js b/src/levels/advanced/multipleParents.js index 4a67f00d..1fa2c1f9 100644 --- a/src/levels/advanced/multipleParents.js +++ b/src/levels/advanced/multipleParents.js @@ -1,6 +1,6 @@ exports.level = { "goalTreeString": "{\"branches\":{\"master\":{\"target\":\"C7\",\"id\":\"master\"},\"bugWork\":{\"target\":\"C2\",\"id\":\"bugWork\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C3\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C2\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C4\",\"C5\"],\"id\":\"C6\"},\"C7\":{\"parents\":[\"C6\"],\"id\":\"C7\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}", - "solutionCommand": "git branch bugWork master^^2^", + "solutionCommand": "git branch bugWork main^^2^", "startTree": "{\"branches\":{\"master\":{\"target\":\"C7\",\"id\":\"master\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C3\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C2\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C4\",\"C5\"],\"id\":\"C6\"},\"C7\":{\"parents\":[\"C6\"],\"id\":\"C7\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}", "name": { "en_US": "Multiple parents", @@ -9,11 +9,17 @@ exports.level = { "de_DE": "Mehrere Vorgänger", "ja" : "複数の親", "es_AR": "Múltiples padres", + "es_MX": "Múltiples padres", + "es_ES": "Múltiples padres", "pt_BR": "Múltiplos pais", + "gl" : "Múltiples pais", "zh_TW": "多個 parent commit", "ru_RU": "Здоровая семья, или несколько родителей", "ko" : "다수의 부모", - 'uk': 'Декілька батьків' + 'uk': 'Декілька батьків', + 'vi': 'Nhiều cha lắm mẹ', + 'sl_SI': 'Več Staršev', + 'ta_IN': 'ஒன்றுக்கு மேற்ப்பட்ட துவக்க கிலைகள்' }, "hint": { "en_US": "Use `git branch bugWork` with a target commit to create the missing reference.", @@ -22,11 +28,17 @@ exports.level = { 'fr_FR': 'Utilisez "git branch bugWork" avec un commit pour créer une référence manquante', "zh_CN": "使用 `git branch bugWork` 加上一个目标提交记录来创建消失的引用。", "es_AR": "Usá `git branch bugWork` sobre algún commit para crear la referencia faltante", + "es_MX": "Use `git branch bugWork` sobre algún commit para crear la referencia faltante", + "es_ES": "Usa `git branch bugWork` sobre algún commit para crear la referencia que falta", "pt_BR": "Use `git branch bugWork` com um commit alvo para criar a referência que falta", + "gl" : "Usa `git branch bugWork` sobre calquera commit para crear a referencia que falta", "zh_TW": "在一個指定的 commit 上面使用 `git branch bugWork`。", "ru_RU": "`git branch bugWork` на нужном коммите поможет создать нужную ссылку.", "ko" : "`git branch bugWork`를 대상 커밋과 함께 사용해서 부족한 참조를 만드세요", - 'uk': 'Використай "git branch bugWork" на потрібному коміті щоб створити потрібне посилання' + 'uk': 'Використай "git branch bugWork" на потрібному коміті щоб створити потрібне посилання', + 'vi': 'Dùng lệnh `git branch bugWork` để tạo nhánh tại vị trí chỉ định', + 'sl_SI': 'Uporabi `git branch bugWork` s ciljnim commitom za ustvarjanje manjkajoče reference.', + "ta_IN": "`git branch bugWork` பயன்படுத்தி தேவைப்படும் கமிட்டுடன் இழந்த இணைப்பை உருவாக்குக." }, "startDialog": { "en_US": { @@ -52,15 +64,15 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Here we have a merge commit. If we checkout `master^` without the modifier, we will follow the first parent after the merge commit. ", + "Here we have a merge commit. If we checkout `main^` without the modifier, we will follow the first parent after the merge commit. ", "", "(*In our visuals, the first parent is positioned directly above the merge commit.*)" ], "afterMarkdowns": [ "Easy -- this is what we are all used to." ], - "command": "git checkout master^", - "beforeCommand": "git checkout HEAD^; git commit; git checkout master; git merge C2" + "command": "git checkout main^", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" } }, { @@ -72,8 +84,8 @@ exports.level = { "afterMarkdowns": [ "See? We followed the other parent upwards." ], - "command": "git checkout master^2", - "beforeCommand": "git checkout HEAD^; git commit; git checkout master; git merge C2" + "command": "git checkout main^2", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" } }, { @@ -86,7 +98,7 @@ exports.level = { "Lightning fast!" ], "command": "git checkout HEAD~; git checkout HEAD^2; git checkout HEAD~2", - "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout master; git merge C5; git commit" + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" } }, { @@ -99,7 +111,7 @@ exports.level = { "The same movement as before, but all in one command." ], "command": "git checkout HEAD~^2~2", - "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout master; git merge C5; git commit" + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" } }, { @@ -139,15 +151,15 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Hier sehen wir einen Merge-Commit. Wenn wir einen Checkout von `master^` ohne Zahl machen, wird Git auf den ersten Vorgänger des Commits zurückgehen. ", + "Hier sehen wir einen Merge-Commit. Wenn wir einen Checkout von `main^` ohne Zahl machen, wird Git auf den ersten Vorgänger des Commits zurückgehen. ", "", "*(In unserer Darstellung befindet sich der erste Vorgänger direkt über dem Merge-Commit.)*" ], "afterMarkdowns": [ "Simpel -- so kennen wir das." ], - "command": "git checkout master^", - "beforeCommand": "git checkout HEAD^; git commit; git checkout master; git merge C2" + "command": "git checkout main^", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" } }, { @@ -159,8 +171,8 @@ exports.level = { "afterMarkdowns": [ "Gesehen? Wir gehen zu dem anderen Vorgänger zurück." ], - "command": "git checkout master^2", - "beforeCommand": "git checkout HEAD^; git commit; git checkout master; git merge C2" + "command": "git checkout main^2", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" } }, { @@ -173,7 +185,7 @@ exports.level = { "Bämm!" ], "command": "git checkout HEAD~; git checkout HEAD^2; git checkout HEAD~2", - "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout master; git merge C5; git commit" + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" } }, { @@ -186,7 +198,7 @@ exports.level = { "Gleicher Ablauf wie zuvor, nur alles in einem Befehl." ], "command": "git checkout HEAD~^2~2", - "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout master; git merge C5; git commit" + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" } }, { @@ -209,13 +221,13 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "### Determine les Parents", + "### Détermine les parents", "", "Comme le symbole `~`, le symbole `^` accepte un numéro après lui.", "", "Au lieu d'entrer le nombre de générations à remonter (ce que `~` fait), le symbole `^` détermine quel parent est à remonter. Attention, un merge commit a deux parents ce qui peut porter à confusion.", "", - "Normalement Git suit le \"premier\" parent pour un commit/merge, mais avec un numéro suivi de `^` le comportement par défault est modifié.", + "Normalement Git suit le \"premier\" parent pour un commit/merge, mais avec un numéro suivi de `^` le comportement par défaut est modifié.", "", "Assez de bla bla, passons à l\'action", "" @@ -226,15 +238,15 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Nous avons un commit/merge. Si nous faisons checkout `master^` sans le symbole, on obtient le premier parent suivant ce commit. ", + "Nous avons un commit/merge. Si nous faisons checkout `main^` sans le symbole, on obtient le premier parent suivant ce commit. ", "", "(*Dans notre vue, le premier parent se situe juste au dessus du merge.*)" ], "afterMarkdowns": [ "Facile -- C\'est ce que nous faisons tout le temps." ], - "command": "git checkout master^", - "beforeCommand": "git checkout HEAD^; git commit; git checkout master; git merge C2" + "command": "git checkout main^", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" } }, { @@ -246,8 +258,8 @@ exports.level = { "afterMarkdowns": [ "Vous voyez ? Nous suivons le second parent." ], - "command": "git checkout master^2", - "beforeCommand": "git checkout HEAD^; git commit; git checkout master; git merge C2" + "command": "git checkout main^2", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" } }, { @@ -260,7 +272,7 @@ exports.level = { "Boum, vitesse du tonnerre !" ], "command": "git checkout HEAD~; git checkout HEAD^2; git checkout HEAD~2", - "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout master; git merge C5; git commit" + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" } }, { @@ -273,7 +285,7 @@ exports.level = { "Le même résultat, mais en une seule commande." ], "command": "git checkout HEAD~^2~2", - "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout master; git merge C5; git commit" + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" } }, { @@ -282,7 +294,7 @@ exports.level = { "markdowns": [ "### Un peu de pratique", "", - "Pour réussir le niveau, créez une nouvelle branche à la destination indiquée", + "Pour réussir le niveau, créez une nouvelle branche à la destination indiquée.", "", "Évidement ce serait plus rapide de spécifier le commit (C6 par exemple), mais faites-le plutôt avec les symboles de déplacement dont nous venons de parler !" ] @@ -313,15 +325,15 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "这里有一个合并提交记录。如果不加数字修改符直接检出 `master^`,会回到第一个父提交记录。", + "这里有一个合并提交记录。如果不加数字修改符直接检出 `main^`,会回到第一个父提交记录。", "", "(*在我们的图示中,第一个父提交记录是指合并提交记录正上方的那个提交记录。*)" ], "afterMarkdowns": [ "这正是我们都已经习惯的方法。" ], - "command": "git checkout master^", - "beforeCommand": "git checkout HEAD^; git commit; git checkout master; git merge C2" + "command": "git checkout main^", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" } }, { @@ -333,8 +345,8 @@ exports.level = { "afterMarkdowns": [ "看见了吧?我们回到了另外一个父提交上。" ], - "command": "git checkout master^2", - "beforeCommand": "git checkout HEAD^; git commit; git checkout master; git merge C2" + "command": "git checkout main^2", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" } }, { @@ -347,7 +359,7 @@ exports.level = { "快若闪电!" ], "command": "git checkout HEAD~; git checkout HEAD^2; git checkout HEAD~2", - "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout master; git merge C5; git commit" + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" } }, { @@ -360,7 +372,7 @@ exports.level = { "和前面的结果一样,但只用了一条命令。" ], "command": "git checkout HEAD~^2~2", - "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout master; git merge C5; git commit" + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" } }, { @@ -400,15 +412,15 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Acá tenemos un commit de merge. Si hacemos checkout de `master^`, sin modificadores, vamos a seguir al primer padre después del commit de merge. ", + "Acá tenemos un commit de merge. Si hacemos checkout de `main^`, sin modificadores, vamos a seguir al primer padre después del commit de merge. ", "", "(*En nuestras visualizaciones, el primer padre se ubica directamente arriba del commit de merge.*)" ], "afterMarkdowns": [ "Fácil -- esto es a lo que estamos acostumbrados." ], - "command": "git checkout master^", - "beforeCommand": "git checkout HEAD^; git commit; git checkout master; git merge C2" + "command": "git checkout main^", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" } }, { @@ -420,8 +432,8 @@ exports.level = { "afterMarkdowns": [ "¿Ves? Seguimos al otro padre hacia arriba." ], - "command": "git checkout master^2", - "beforeCommand": "git checkout HEAD^; git commit; git checkout master; git merge C2" + "command": "git checkout main^2", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" } }, { @@ -434,7 +446,7 @@ exports.level = { "¡Rapidísimo!" ], "command": "git checkout HEAD~; git checkout HEAD^2; git checkout HEAD~2", - "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout master; git merge C5; git commit" + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" } }, { @@ -447,7 +459,7 @@ exports.level = { "El mismo movimiento que antes, pero todo en uno." ], "command": "git checkout HEAD~^2~2", - "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout master; git merge C5; git commit" + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" } }, { @@ -458,7 +470,181 @@ exports.level = { "", "Para completar este nivel, creá una nueva rama en la ubicación indicada.", "", - "Obviamente sería muy fácil especificar el commit directamente (algo como `C6`), pero te reto a usar los modificadores de los que estuvimos hablando, mejor" + "Obviamente sería muy fácil especificar el commit directamente (algo como `C6`), pero te reto a usar los modificadores de los que estuvimos hablando, mejor." + ] + } + } + ] + }, + "es_MX": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Especificando los padres", + "", + "Como el modificador de `~`, `^` también acepta un número opcional después de él.", + "", + "En lugar de especificar cuántas generaciones hacia atrás ir (como `~`), el modificador de `^` especifica por cuál de las referencias padres seguir en un commit de merge. Recuerda que un commit de merge tiene múltiples padres, por lo que el camino a seguir es ambiguo.", + "", + "Git normalmente sigue el \"primer\" padre de un commit de merge, pero especificando un número junto con `^` cambia este comportamiento predefinido.", + "", + "Demasiada charla, veámoslo en acción.", + "" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Acá tenemos un commit de merge. Si hacemos checkout de `main^`, sin modificadores, vamos a seguir al primer padre después del commit de merge. ", + "", + "(*En nuestras visualizaciones, el primer padre se ubica directamente arriba del commit de merge.*)" + ], + "afterMarkdowns": [ + "Fácil -- esto es a lo que estamos acostumbrados." + ], + "command": "git checkout main^", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Ahora tratemos de especificar el segundo padre, en cambio..." + ], + "afterMarkdowns": [ + "¿Ves? Seguimos al otro padre hacia arriba." + ], + "command": "git checkout main^2", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Los modificadores de `^` y `~` son muy poderosos a la hora de movernos en un árbol:" + ], + "afterMarkdowns": [ + "¡Rapidísimo!" + ], + "command": "git checkout HEAD~; git checkout HEAD^2; git checkout HEAD~2", + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Más loco aún, ¡Éstos modificadores pueden encadenarse entre sí! Mira esto:" + ], + "afterMarkdowns": [ + "El mismo movimiento que antes, pero todo en uno." + ], + "command": "git checkout HEAD~^2~2", + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Pongámoslo en práctica", + "", + "Para completar este nivel, crea una nueva rama en la ubicación indicada.", + "", + "Obviamente sería muy fácil especificar el commit directamente (algo como `C6`), pero te reto a usar los modificadores de los que estuvimos hablando, mejor." + ] + } + } + ] + }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Especificando los padres", + "", + "Como el modificador de `~`, `^` también acepta un número opcional después de él.", + "", + "En lugar de especificar cuántas generaciones hacia atrás ir (como `~`), el modificador de `^` especifica por cuál de las referencias padres seguir en un commit de merge. Recuerda que un commit de merge tiene múltiples padres, por lo que el camino a seguir es ambiguo.", + "", + "Git normalmente sigue el \"primer\" padre de un commit de merge, pero especificando un número junto con `^` cambia este comportamiento predefinido.", + "", + "Demasiada charla, veámoslo en acción.", + "" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Aquí tenemos un commit de merge. Si hacemos checkout de `main^`, sin modificadores, vamos a seguir al primer padre después del commit de merge. ", + "", + "(*En nuestras visualizaciones, el primer padre se ubica directamente arriba del commit de merge.*)" + ], + "afterMarkdowns": [ + "Fácil -- esto es a lo que estamos acostumbrados." + ], + "command": "git checkout main^", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Ahora tratemos de especificar el segundo padre, en cambio..." + ], + "afterMarkdowns": [ + "¿Ves? Seguimos al otro padre hacia arriba." + ], + "command": "git checkout main^2", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Los modificadores de `^` y `~` son muy poderosos a la hora de movernos en un árbol:" + ], + "afterMarkdowns": [ + "¡Rapidísimo!" + ], + "command": "git checkout HEAD~; git checkout HEAD^2; git checkout HEAD~2", + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Más loco aún, ¡estos modificadores pueden encadenarse entre sí! Mira esto:" + ], + "afterMarkdowns": [ + "El mismo movimiento que antes, pero todo en uno." + ], + "command": "git checkout HEAD~^2~2", + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Ponlo en práctica", + "", + "Para completar este nivel, crea una nueva rama en la ubicación indicada.", + "", + "Obviamente sería muy fácil especificar el commit directamente (algo como `C6`), pero te reto a usar los modificadores de los que estuvimos hablando, mejor." ] } } @@ -487,15 +673,15 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Aqui temos um commit de merge. Se fizermos checkout em `master^` sem especificar um número, vamos seguir o primeiro pai acima do commit de merge. ", + "Aqui temos um commit de merge. Se fizermos checkout em `main^` sem especificar um número, vamos seguir o primeiro pai acima do commit de merge. ", "", "(*Em nossa visualização, o primeiro pai é aquele diretamente acima do commit de merge.*)" ], "afterMarkdowns": [ "Fácil -- isso é aquilo com o que já estamos acostumados." ], - "command": "git checkout master^", - "beforeCommand": "git checkout HEAD^; git commit; git checkout master; git merge C2" + "command": "git checkout main^", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" } }, { @@ -507,8 +693,8 @@ exports.level = { "afterMarkdowns": [ "Viu? Subimos para o outro pai." ], - "command": "git checkout master^2", - "beforeCommand": "git checkout HEAD^; git commit; git checkout master; git merge C2" + "command": "git checkout main^2", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" } }, { @@ -521,7 +707,7 @@ exports.level = { "Rápido como a luz!" ], "command": "git checkout HEAD~; git checkout HEAD^2; git checkout HEAD~2", - "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout master; git merge C5; git commit" + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" } }, { @@ -534,7 +720,7 @@ exports.level = { "O mesmo movimento que o anterior, mas tudo em um único comando." ], "command": "git checkout HEAD~^2~2", - "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout master; git merge C5; git commit" + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" } }, { @@ -551,6 +737,94 @@ exports.level = { } ] }, + + "gl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Especificando pais", + "", + "Tanto o modificador `~`, como o modificador `^` aceptan un número opcional despois del.", + "", + "Mellor que especificar o número de commits que percorrer cara atrás (que é o que o `~` fai), o modificador sobre `^` especifica qué referencia do pai vai ser seguida dende o commit con merge. Lembra qué os commits do merge teñen varios pais, entón o camiño a seguir é ambiguo.", + "", + "Git normalmente seguirá ó \"primeiro\" pai de un commit de merge, pero especificando un número co `^` muda o comportamento do pai.", + "", + "Xa chega de faladoiros, vexamos o comando en acción.", + "" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Aquí temos un commit do merge. Se fixéramos checkout en `main^` sen especificar un número, imos seguir ó primeiro pai enriba do commit do merge. ", + "", + "(*Na nosa vista, o primeiro pai é aquel directamente enriba do commit do merge.*)" + ], + "afterMarkdowns": [ + "Sinxelo, eso é aquelo co que xa estamos acostumados." + ], + "command": "git checkout main^", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Agora imos, en vez de iso, especificar o segundo pai..." + ], + "afterMarkdowns": [ + "¿Viches? Subimos para o outro pai." + ], + "command": "git checkout main^2", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Os modificadores `^` e `~` pódense mover ao redor da árbore de commits con moito poder:" + ], + "afterMarkdowns": [ + "Rápido coma a luz!" + ], + "command": "git checkout HEAD~; git checkout HEAD^2; git checkout HEAD~2", + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Aínda máis tolo, eses modificadores poden ser encadeados en conxunto! Olla ahí:" + ], + "afterMarkdowns": [ + "O mesmo movemento feito antes, pero feito nun só comando." + ], + "command": "git checkout HEAD~^2~2", + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Pono na práctica", + "", + "Para completar este nível, crea unha nova rama no destino especificado.", + "", + "Obviamente sería máis sinxelo especificar o commit diretamente (algo como `C6`), pero en vez de facer eso, ¡podes usar os modificadores dos que falamos!" + ] + } + } + ] + }, "zh_TW": { "childViews": [ { @@ -574,15 +848,15 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "這裡有一個 merge commit。如果後面不加數字的話會直接切換到`master^`,也就是說會回到第一個 parent commit。", + "這裡有一個 merge commit。如果後面不加數字的話會直接切換到`main^`,也就是說會回到第一個 parent commit。", "", "(*在我們的圖示中,第一個 parent commit 是指 merge commit 正上方的那一個 parent commit。*)" ], "afterMarkdowns": [ "簡單吧!這就是預設的情況。" ], - "command": "git checkout master^", - "beforeCommand": "git checkout HEAD^; git commit; git checkout master; git merge C2" + "command": "git checkout main^", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" } }, { @@ -594,8 +868,8 @@ exports.level = { "afterMarkdowns": [ "看到了嗎?我們回到了第二個 parent commit。" ], - "command": "git checkout master^2", - "beforeCommand": "git checkout HEAD^; git commit; git checkout master; git merge C2" + "command": "git checkout main^2", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" } }, { @@ -608,7 +882,7 @@ exports.level = { "簡直就像是電光石火!" ], "command": "git checkout HEAD~; git checkout HEAD^2; git checkout HEAD~2", - "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout master; git merge C5; git commit" + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" } }, { @@ -621,7 +895,7 @@ exports.level = { "和前面的結果一樣,但只用了一條指令。" ], "command": "git checkout HEAD~^2~2", - "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout master; git merge C5; git commit" + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" } }, { @@ -661,15 +935,15 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Вот мерджевый коммит. Если мы перейдём на `master^` без номера, то попадём на первого родителя.", + "Вот мерджевый коммит. Если мы перейдём на `main^` без номера, то попадём на первого родителя.", "", "(*На нашей визуализации первый родитель находится прямо над коммитом*)" ], "afterMarkdowns": [ "Просто - прямо как мы любим." ], - "command": "git checkout master^", - "beforeCommand": "git checkout HEAD^; git commit; git checkout master; git merge C2" + "command": "git checkout main^", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" } }, { @@ -681,8 +955,8 @@ exports.level = { "afterMarkdowns": [ "Вот. Мы на втором родительском коммите." ], - "command": "git checkout master^2", - "beforeCommand": "git checkout HEAD^; git commit; git checkout master; git merge C2" + "command": "git checkout main^2", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" } }, { @@ -695,7 +969,7 @@ exports.level = { "Быстро как Флэш!" ], "command": "git checkout HEAD~; git checkout HEAD^2; git checkout HEAD~2", - "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout master; git merge C5; git commit" + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" } }, { @@ -708,7 +982,7 @@ exports.level = { "Сделаем то же самое, что перед этим, только в одну команду." ], "command": "git checkout HEAD~^2~2", - "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout master; git merge C5; git commit" + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" } }, { @@ -748,15 +1022,15 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "ここに、マージコミットがあります。もし、指定無しに`master^`でチェックアウトした場合、私たちは一番目の親に移動することになります。", + "ここに、マージコミットがあります。もし、指定無しに`main^`でチェックアウトした場合、私たちは一番目の親に移動することになります。", "", "(*私たちのツリーでは、一番目の親はマージコミットのちょうど上に位置しています。*)" ], "afterMarkdowns": [ "簡単ですね -- これがデフォルトの動作になります。" ], - "command": "git checkout master^", - "beforeCommand": "git checkout HEAD^; git commit; git checkout master; git merge C2" + "command": "git checkout main^", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" } }, { @@ -768,8 +1042,8 @@ exports.level = { "afterMarkdowns": [ "見ましたか?私たちは他の親に移ることができました。" ], - "command": "git checkout master^2", - "beforeCommand": "git checkout HEAD^; git commit; git checkout master; git merge C2" + "command": "git checkout main^2", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" } }, { @@ -782,7 +1056,7 @@ exports.level = { "超高速ですね!" ], "command": "git checkout HEAD~; git checkout HEAD^2; git checkout HEAD~2", - "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout master; git merge C5; git commit" + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" } }, { @@ -795,7 +1069,7 @@ exports.level = { "前と同じ移動ですが、なんと一つのコマンドでできています。" ], "command": "git checkout HEAD~^2~2", - "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout master; git merge C5; git commit" + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" } }, { @@ -824,7 +1098,7 @@ exports.level = { "", "몇개의 세대를 돌아갈지 정하는 것 대신(`~`의 기능) `^`수식은 병합이된 커밋에서 어떤 부모를 참조할지 선택할 수 있습니다. 병합된 커밋들은 다수의 부모를 가지고 있다는것을 기억하시나요? 어떤 부모를 선택할지 예측할 수가 없습니다.", "", - "Git은 보통 병합된 커밋에서 \"첫\"부모를 따라갑니다. 하지만 `^`수식을 를 숫자와 함께 사용하면 앞의 디폴트 동작대로가 아닌 다른 결과가 나타납니다.", + "Git은 보통 병합된 커밋에서 \"첫\" 부모를 따라갑니다. 하지만 `^`수식을 숫자와 함께 사용하면 앞의 디폴트 동작대로가 아닌 다른 결과가 나타납니다.", "", "이만 줄이고, 직접 확인해봅시다.", "" @@ -835,15 +1109,15 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "여기 병합된 커밋이 있습니다. 우리가 `master`를 수식없이 체크아웃한다면 병합된 커밋의 첫 부모를 따라 올라갈 것입니다. ", + "여기 병합된 커밋이 있습니다. 우리가 `main`를 수식없이 체크아웃한다면 병합된 커밋의 첫 부모를 따라 올라갈 것입니다. ", "", "(*화면에서는 첫 부모는 병합된 커밋 바로 위에 위치해 있습니다.*)" ], "afterMarkdowns": [ "간단하죠 -- 우리한테 익숙한 모습입니다." ], - "command": "git checkout master^", - "beforeCommand": "git checkout HEAD^; git commit; git checkout master; git merge C2" + "command": "git checkout main^", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" } }, { @@ -855,8 +1129,8 @@ exports.level = { "afterMarkdowns": [ "보이나요? 다른 부모를 선택해 올라갔습니다." ], - "command": "git checkout master^2", - "beforeCommand": "git checkout HEAD^; git commit; git checkout master; git merge C2" + "command": "git checkout main^2", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" } }, { @@ -869,7 +1143,7 @@ exports.level = { "빛처럼 빠르게 말이죠!" ], "command": "git checkout HEAD~; git checkout HEAD^2; git checkout HEAD~2", - "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout master; git merge C5; git commit" + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" } }, { @@ -882,7 +1156,7 @@ exports.level = { "앞과 같은 움직임이지만 하나의 명령으로 표현되었습니다." ], "command": "git checkout HEAD~^2~2", - "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout master; git merge C5; git commit" + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" } }, { @@ -922,15 +1196,15 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Ось ми маємо мерджевий коміт. Якщо зробимо checkout `master^` без числа, ми потрапимо на першого з предків ", + "Ось ми маємо мерджевий коміт. Якщо зробимо checkout `main^` без числа, ми потрапимо на першого з предків ", "", "(*В нашій візуалізації перший предок знаходиться прямо над мерджевим комітом*)" ], "afterMarkdowns": [ "Легко -- те до чого ми всі звикли." ], - "command": "git checkout master^", - "beforeCommand": "git checkout HEAD^; git commit; git checkout master; git merge C2" + "command": "git checkout main^", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" } }, { @@ -942,8 +1216,8 @@ exports.level = { "afterMarkdowns": [ "Бачиш? Ми перейшли до другого батька вверх." ], - "command": "git checkout master^2", - "beforeCommand": "git checkout HEAD^; git commit; git checkout master; git merge C2" + "command": "git checkout main^2", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" } }, { @@ -956,7 +1230,7 @@ exports.level = { "Супер швидко!" ], "command": "git checkout HEAD~; git checkout HEAD^2; git checkout HEAD~2", - "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout master; git merge C5; git commit" + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" } }, { @@ -969,7 +1243,7 @@ exports.level = { "Те саме, що й перед цим, але однією командою." ], "command": "git checkout HEAD~^2~2", - "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout master; git merge C5; git commit" + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" } }, { @@ -985,6 +1259,267 @@ exports.level = { } } ] + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Tìm về cội nguồn", + "", + "Cũng giống ký hiệu `~`, ta cũng có thể thêm số theo sau ký hiệu `^`.", + "", + "Nhưng mà không giống như (`~`) con số theo sau là số lượng thế hệ commit, con số theo sau `^` chỉ định commit cha từ commit merge. Hãy nhớ rằng commit merge có nhiều cha, cho nên chọn cha nào cũng khá là mơ hồ.", + "", + "Thông thường thì sẽ chọn cha \"đầu tiên\" từ commit merge, nhưng nếu sau dấu `^` có một con số thì cách hành xử sẽ khác đi.", + "", + "Không nói dông dài nữa, làm thử một ví dụ nào", + "" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Ở đây ta có 1 commit merge. Nếu ta dùng lệnh `main^` mà không bổ nghĩa cho nó, ta sẽ đi ngược lên commit cha đầu tiên của merge commit. ", + "", + "(*Trong hình minh họa bên trái thì commit cha đầu tiên được xếp hẳng hàng ngay phía trên của commit merge.*)" + ], + "afterMarkdowns": [ + "Dễ dàng -- đó là cách mà ta thường làm." + ], + "command": "git checkout main^", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Nào bây giờ hãy chỉ định commit cha thứ hai thử..." + ], + "afterMarkdowns": [ + "Thấy chứ? Ta đã leo lên commit cha khác lúc trước." + ], + "command": "git checkout main^2", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Dùng bổ ngữ `^` và `~` cho ta khả năng di chuyển trên cây lịch sử:" + ], + "afterMarkdowns": [ + "Nhanh như chớp!" + ], + "command": "git checkout HEAD~; git checkout HEAD^2; git checkout HEAD~2", + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Thâm chí còn ghê gớm hơn khi ta kết hợp chúng với nhau! Hãy xem thử:" + ], + "afterMarkdowns": [ + "Cùng con đường như lúc trước, nhưng chỉ cần 1 dòng lệnh." + ], + "command": "git checkout HEAD~^2~2", + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Áp dụng thực hành nào", + "", + "Để hoàn thành cấp độ này, hãy tạo ra một nhánh mới ở vị trí chỉ định.", + "", + "Dùng cách chỉ định trực tiếp commit (như là dùng `C6` chẳng hạn) thì dễ quá, nhưng thử thách ở đây là dùng các bổ ngữ đã học ở trên!" + ] + } + } + ] + }, + "sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Določanje Staršev", + "", + "Tako kot `~` modifikator, tudi `^` modifikator sprejme opcijsko število na koncu.", + "", + "Raje kot podajanje števila generacij, za katere se hočemo premakniti nazaj (kot pri `~`), modifikator `^` pove kateremu staršu oz. njegovi referenci naj sledi iz merge commita. Zapomni si, da imajo merge commiti več staršev, zato je pot nejasna.", + "", + "Git bo ponavadi sledil \"prvemu\" staršu navzgor po merge commitu, ampak določitev števila s `^` spremeni privzeto obnašanje.", + "", + "Dovolj govorjenja, poglejmo stvar v akciji.", + "" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Tukaj imamo merge commit. Če checkoutamo `main^` brez modifikatorjev, bomo sledili prvem staršu po merge commitu. ", + "", + "(* V naši vizualizaciji, je postavljen prvi starš direktno nad merge commitom.)" + ], + "afterMarkdowns": [ + "Enostavno -- tega smo vsi navajeni." + ], + "command": "git checkout main^", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Sedaj pa poizkusimo določiti raje drugega starša ..." + ], + "afterMarkdowns": [ + "Vidiš? Sledili smo drugemu staršu navzgor." + ], + "command": "git checkout main^2", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Modifikatorja `^` in `~` naredita sprehajanje po drevesu zelo učinkovito:" + ], + "afterMarkdowns": [ + "Bliskovito!" + ], + "command": "git checkout HEAD~; git checkout HEAD^2; git checkout HEAD~2", + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Še bolj noro, te modifikatorji so lahko povezani skupaj! Poglej to:" + ], + "afterMarkdowns": [ + "Isto gibanje kot prej, ampak vse z enim ukazom." + ], + "command": "git checkout HEAD~^2~2", + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Preizkusi v praksi", + "", + "Za dokončanje te stopnje, ustvari nov brench na določeni destinaciji.", + "", + "Seveda bi bilo lažje izbrati commit direktno (npr. s `C6`), ampak te izzivam, da namesto tega poizkusiš z modifikatorji o katerih smo govorili!" + ] + } + } + ] + }, + "ta_IN": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### துவக்க கிலையை குறிக்க", + "", + "`~` மாற்றியை போல, `^` மாற்றியும் தேவைப்படின் உள்ளீடாக ஒரு எண்யை ஏற்றுக்கொள்ளும், ஆனால் அது கட்டாயம் அல்ல.", + "", + "அந்த எண் (`~` போல்) முந்தய கிழை இணைப்புகளுக்கு பின்னோக்கி செல்வதை குறிக்காமல், தற்ப்போதிய கமிட் எந்த கிழை துவக்கத்துடன் இணைக்க வேண்டுமோ அதனை `^`-இன் உள்ளீடு குறிக்கிரது. தொகுப்பு கமிட்கள் ஒன்றுக்கும் மேற்ப்பட்ட மூல கிழைகளை கொண்டு இருக்கும் எனவே இது குழப்பமானதாக இருக்கும்.", + "", + "கிட் பொதுவாக தொகுப்பு கமிட்டில் இருந்து மேல் நோக்கி உள்ள \"முதல்\" கிழைக்கு பின் இணைப்பை உருவாக்கும், ஆனால் `^`-இற்க்கு கொடுக்கப்படு் உள்ளீட்டு எண் வேரு கிழை முனைப்புகளுடன் இணைக்கி உதவும்.", + "", + "விவரங்கள் போதும், அதை செயலில் பார்ப்போம்.", + "" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "இங்கே நாம்மிடன் ஒரு தொகுப்பு கமிட் உள்ளது. இப்போது நாம் checkout `main^` மட்டும் எந்த ஒரு எண்னும் குறிப்பிடாமல் கட்டலையிட்டால் அது கமிட்டின் நேரடி மூல கிழையுடன் இணைப்பை உருவாக்கும். ", + "", + "(*இங்குள்ள வரைபடத்தில், நேரடி மூழம் தொகுப்பு கமிட்டின் நேர் எதிர் திசையில் மேலக காட்ட பட்டுள்ளது.*)" + ], + "afterMarkdowns": [ + "அது பரவாயில்லை -- இது நாம் அனைவரும் பழக்கமாகிவிட்டது." + ], + "command": "git checkout main^", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "இப்போது நாம் மாற்றாக இரண்டாவது துவக்க கிழையை குறிக்க செய்வோம்..." + ], + "afterMarkdowns": [ + "கவனத்தீர்களா? நாம் அடுத்த கிழை மூழப்புள்ளியின் கீழ் இணைப்பை உருவாக்கி உள்ளொம்." + ], + "command": "git checkout main^2", + "beforeCommand": "git checkout HEAD^; git commit; git checkout main; git merge C2" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "`^` மற்றும் `~` மாற்றிகள் கமிட் மர அமைப்பை சுலபமாக சுற்றி வர உதவுகின்றன:" + ], + "afterMarkdowns": [ + "மின்னல் வேகம்!" + ], + "command": "git checkout HEAD~; git checkout HEAD^2; git checkout HEAD~2", + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "மேலும் ஒரு எளிய வழி, இந்த மாற்றிகளை நாம் இணைத்தும் பயன் படுத்தலாம்! இதைப்பாருங்க்:" + ], + "afterMarkdowns": [ + "மேல் கண்ட அதே வழி மாற்றம்தான் ஆனால் அனைத்தும் ஒரே கட்டளையில்." + ], + "command": "git checkout HEAD~^2~2", + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout main; git merge C5; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### இப்போது நீங்கள் பயிற்சி செய்யுங்கள்", + "", + "இந்த படி நிலையை நிரைவு செய்ய, குறிப்பிட்டபட்டுள்ள பிரிவில் ஒரு கிளையை உருவாக்குங்கள்.", + "", + "வெளிப்படையாக சொல்லப்போனால் (`C6` போன்று) நேரடியாக கிழையை குறிப்பிடமுடியுன், இருப்பினும் இந்த சவால் மேல் குறிப்பிட்ட மாற்றிகளை பயன் படுத்தும் வகையில் அமைக்க பட்டுள்ளது!" + ] + } + } + ] } } }; diff --git a/src/levels/index.js b/src/levels/index.js index af38e18a..43dbdf91 100644 --- a/src/levels/index.js +++ b/src/levels/index.js @@ -36,7 +36,8 @@ exports.levelSequences = { require('./remote/pull').level, require('./remote/fakeTeamwork').level, require('./remote/push').level, - require('./remote/fetchRebase').level + require('./remote/fetchRebase').level, + require('./remote/lockedMaster').level ], remoteAdvanced: [ require('./remote/pushManyFeatures').level, @@ -59,12 +60,19 @@ var sequenceInfo = exports.sequenceInfo = { 'ja' : 'まずはここから', 'fr_FR': 'Séquence d\'introduction', 'es_AR': 'Secuencia introductoria', + 'es_MX': 'Secuencia introductoria', + 'es_ES': 'Secuencia introductoria', 'pt_BR': 'Sequência introdutória', + 'gl' : 'Secuencia introductoria', 'zh_CN': '基础篇', 'zh_TW': '基礎篇', 'ko' : 'git 기본', 'ru_RU': 'Введение', - 'uk' : 'Вступ' + 'uk' : 'Вступ', + 'vi' : 'Giới thiệu chuỗi luyện tập', + 'sl_SI': 'Uvodno Zaporedje', + 'pl' : 'Wprowadzenie', + 'ta_IN': 'அறிமுக தொடர் வரிசை' }, about: { 'en_US': 'A nicely paced introduction to the majority of git commands', @@ -72,12 +80,19 @@ var sequenceInfo = exports.sequenceInfo = { 'ja' : 'gitの基本的なコマンド群をほどよいペースで学ぶ', 'fr_FR': 'Une introduction en douceur à la majorité des commandes git', 'es_AR': 'Una breve introducción a la mayoría de los comandos de git', + 'es_MX': 'Una breve introducción a la mayoría de los comandos de git', + 'es_ES': 'Una breve introducción a la mayoría de los comandos de git', 'pt_BR': 'Uma breve introdução à maioria dos comandos do git', + 'gl' : 'Unha breve introducción á maioría dos comandos de git', 'zh_CN': '循序渐进地介绍 Git 主要命令', 'zh_TW': '循序漸進地介紹 git 主要命令', 'ko' : 'git의 주요 명령어를 깔끔하게 알려드립니다', 'ru_RU': 'Хорошо подобранное введение в основные команды git', - 'uk' : 'Гарно підібране введення в основні команди git' + 'uk' : 'Гарно підібране введення в основні команди git', + 'vi' : 'Từng bước làm quen với phần lớn lệnh điều khiển git', + 'sl_SI': 'Prijeten uvod v git ukaze', + 'pl' : 'Krótkie wprowadzenie do większości poleceń GIT-a', + 'ta_IN': 'பெரும்பாலான கிட் கட்டளைகளுக்கு ஒரு நல்ல அறிமுகம்' } }, rampup: { @@ -87,12 +102,19 @@ var sequenceInfo = exports.sequenceInfo = { 'ja' : '次のレベルに進もう', 'fr_FR': 'Montée en puissance', 'es_AR': 'Acelerando', + 'es_MX': 'Acelerando', + 'es_ES': 'Acelerando', 'pt_BR': 'Acelerando', + 'gl' : 'Alixeirando', 'zh_CN': '高级篇', 'zh_TW': '進階篇', 'ru_RU': 'Едем дальше', 'uk' : 'Їдемо далі', - 'ko' : '다음 단계로' + 'ko' : '다음 단계로', + 'vi' : 'Tăng tốc', + 'sl_SI': 'Prva Stopnička', + 'pl' : 'Rozkręcenie', + 'ta_IN': 'சற்று அதிகப்படுத்த' }, about: { 'en_US': 'The next serving of 100% git awesomes-ness. Hope you\'re hungry', @@ -100,12 +122,19 @@ var sequenceInfo = exports.sequenceInfo = { 'ja' : '更にgitの素晴らしさを堪能しよう', 'fr_FR': 'Le prochain excellent plat de pur git. J\'espère que vous êtes affamés', 'es_AR': 'La próxima porción de 100% maravillas git. Espero que estés hambriento', + 'es_MX': 'La próxima ración de git. Espero que estés hambriento', + 'es_ES': 'La próxima ración de git. Espero que estés hambriento', 'pt_BR': 'A próxima porção de maravilhas do git. Faminto?', + 'gl' : 'A próxima porción das marabillas de git. Agardo que estés esfameado', 'zh_CN': '要开始介绍 Git 的超棒特性了,快来吧!', 'zh_TW': '接下來是 git 非常厲害的地方!相信你已經迫不及待了吧!', 'ru_RU': 'Следующая порция абсолютной git-крутотенюшки. Проголодались?', 'uk' : 'Наступна порція абсолютної git-дивини. Сподіваюсь, ви зголодніли', - 'ko' : 'git은 아주 멋져요. 왜 멋진지 알려드립니다' + 'ko' : 'git은 아주 멋져요. 왜 멋진지 알려드립니다', + 'vi' : 'Tận hưởng khẩu phần tuyệt hảo của git. Hi vọng bạn còn đói.', + 'sl_SI': 'Naslednja porcija git izjemnosti. Upam, da si lačen', + 'pl' : 'Następna porcja GIT-a jest niesamowita. Mam nadzieję, że jesteś głodny', + 'ta_IN': 'அடித்தது கிட்டின் 100% அற்புதங்கள். நீங்கள் ஆர்வமாக உள்ளீர்கள் என்று நம்புகிறேன்' } }, remote: { @@ -116,25 +145,39 @@ var sequenceInfo = exports.sequenceInfo = { 'ja' : 'Push及びPullコマンド -- Gitリモート', 'fr_FR': 'Push & Pull -- dépôts gits distants !', 'es_AR': 'Push & Pull -- Git Remotes!', + 'es_MX': 'Push & Pull -- Repositorios remotos en Git (Git Remotes)!', + 'es_ES': 'Push y Pull -- Git Remotes!', 'pt_BR': 'Push & Pull -- repositórios remotos no Git!', + 'gl' : 'Push & Pull -- Repositorios remotos no Git!', 'zh_CN': 'Push & Pull —— Git 远程仓库!', 'zh_TW': 'Push & Pull -- Git Remotes!', 'ru_RU': 'Push & Pull - удалённые репозитории в Git!', 'uk' : 'Push & Pull -- віддалені репозиторії в Git!', - 'ko' : 'Push & Pull -- Git 원격 저장소!' + 'ko' : 'Push & Pull -- Git 원격 저장소!', + 'vi' : 'Push & Pull -- Tác động git từ xa!', + 'sl_SI': 'Push & Pull -- Oddaljeni Git', + 'pl' : 'Push & Pull -- Zdalne repozytoria', + 'ta_IN': 'Push & Pull -- கிட் Remotes!' }, about: { 'en_US': 'Time to share your 1\'s and 0\'s kids; coding just got social', 'fr_FR': 'C\'est le temps de partager vos 1 et vos 0 les enfants, le code vient de devenir social.', 'ja' : '自分のコードをより広く公開しましょう', - 'de_DE': 'Zeit Eure 1en und 0en zu teilen; Coding mit sozialer Komponente', + 'de_DE': 'Zeit eure 1en und 0en zu teilen; Coding mit sozialer Komponente', 'es_AR': 'Hora de compartir sus 1\'s y 0\'s, chicos; programar se volvió social!', + 'es_MX': 'Hora de compartir sus 1\'s y 0\'s, chicos; programar se volvió social!', + 'es_ES': 'Hora de compartir vuestros 1\'s y 0\'s, chicos; programar se volvió social!', 'pt_BR': 'Hora de compartilhar seus 1\'s e 0\'s, crianças; programar agora é social!', + 'gl' : 'Hora de compartilos seus 1\' e 0\'s, rapaces; programar agora é social!', 'zh_CN': '是时候分享你的代码了,让编码变得社交化吧', 'zh_TW': '是時候分享你的程式碼了', 'ru_RU': 'Настало время поделиться своими единичками и нулями. Время коллективного программирования', 'uk' : 'Настав час поділитися своїми нулями та одиничками; соціальне програмування', - 'ko' : '내 코드를 공개할 때가 되었습니다. 코드를 공개해봅시다!' + 'ko' : '내 코드를 공개할 때가 되었습니다. 코드를 공개해봅시다!', + 'vi' : 'Chia sẻ đứa con tinh thần \'0\' và \'1\' của bạn; mã đã đến với cộng đồng', + 'sl_SI': 'Čas za deljenje tvojih 1 in 0; kodiranje je pravkar postalo socialno', + 'pl' : 'Czas podzielić się swoimi dziećmi 1 i 0; kodowanie właśnie stało się społeczne', + 'ta_IN': 'உங்களின் 1\'கள் மற்றும் 0\'களை பகிர்வதற்கான நேரம் குழந்தைகளே; குறியிடுதல் (coding) பொது உடமை ஆக்க பட்டுள்ளது' } }, remoteAdvanced: { @@ -145,53 +188,81 @@ var sequenceInfo = exports.sequenceInfo = { 'ja' : '"origin"とその先へ -- Gitリモート上級編', 'fr_FR': 'Vers l\'infini et au-delà -- dépôts distants version avancée', 'es_AR': 'Hasta el origin y más allá -- Git Remotes avanzado!', + 'es_MX': 'Hasta el origin y más allá -- Git Remotes avanzado!', + 'es_ES': 'Hasta el origen y más allá -- Git Remotes avanzado!', 'pt_BR': 'Até a origin e além -- repositórios remotos avançados!', + 'gl' : 'Ata á orixe e máis aló -- repositorios remotos avanzados!', 'zh_CN': '关于 origin 和它的周边 —— Git 远程仓库高级操作', 'zh_TW': '關於 origin 和其它 repo,git remote 的進階指令', 'ru_RU': 'Через origin – к звёздам. Продвинутое использование Git Remotes', 'uk' : 'Через origin – до зірок. Прогресивне використання Git Remotes', - 'ko' : '"origin"그 너머로 -- 고급 Git 원격 저장소' + 'ko' : '"origin"그 너머로 -- 고급 Git 원격 저장소', + 'vi' : 'Về với cội nguồn và vươn xa hơn -- nâng cao về các git remote', + 'sl_SI': 'Do Origina In Naprej -- Napredni Oddaljeni Git', + 'pl' : 'Do źródła i dalej -- zaawansowane zdalne repozytoria', + 'ta_IN': 'ஆரம்பம் மற்றும் அதர்க்கு மேல் -- மேம்பட்ட கிட் ரிமோட்டுகள்!' }, about: { 'en_US': 'And you thought being a benevolent dictator would be fun...', 'fr_FR': 'Et vous pensiez qu\'être un dictateur bienfaisant serait amusant...', 'ja' : '絶えず上級者の仕事は存在する。。。', 'es_AR': 'Y pensabas que ser un dictador benévolo sería divertido...', + 'es_MX': 'Y pensabas que ser un dictador benévolo sería divertido...', + 'es_ES': 'Y pensabas que ser un dictador benévolo sería divertido...', 'pt_BR': 'E você achava que ser um déspota esclarecido seria mais divertido...', + 'gl' : 'E pensabas que ser un dictador benévolo sería divertido...', 'zh_CN': '做一名仁慈的独裁者一定会很有趣……', 'zh_TW': '而且你會覺得做一個仁慈的獨裁者會很有趣...', 'de_DE': 'Git Remotes für Fortgeschrittene', 'ru_RU': 'Весело было быть всесильным мудрым правителем...', 'uk' : 'А ти думав, що бути всесильним диктатором весело...', - 'ko' : '자비로운 독재자가 되는게 재밌을 줄 알았겠지만...' + 'ko' : '자비로운 독재자가 되는게 재밌을 줄 알았겠지만...', + 'vi' : 'Và bạn nghĩ làm một kẻ độc tài nhân từ thì sẽ vui ...', + 'sl_SI': 'In ti si mislil, da je biti dobronamerni diktator zabavno ...', + 'pl' : 'A myślałeś, że bycie życzliwym dyktatorem byłoby fajne...', + 'ta_IN': 'நீங்கள் ஒரு அக்கரை உள்ள சர்வாதிகாரியாக இருப்பது வேடிக்கையாக இருக்கும் என்று நினைத்தீர்களா...' } }, move: { displayName: { 'en_US': 'Moving Work Around', - 'de_DE': 'Code Umherschieben', + 'de_DE': 'Code umherschieben', 'fr_FR': 'Déplacer le travail', 'es_AR': 'Moviendo el trabajo por ahí', + 'es_MX': 'Moviendo el trabajo por ahí', + 'es_ES': 'Moviendo el trabajo por ahí', 'pt_BR': 'Movendo trabalho por aí', + 'gl' : 'Movendo o traballo por ahí', 'ja' : 'コードの移動', 'ko' : '코드 이리저리 옮기기', 'zh_CN': '移动提交记录', 'zh_TW': '調整提交順序', 'ru_RU': 'Перемещаем труды туда-сюда', - 'uk' : 'Переміщуємо роботу туди-сюди' + 'uk' : 'Переміщуємо роботу туди-сюди', + 'vi' : 'Điều chỉnh vị trí', + 'sl_SI': 'Premikanje Dela Naokrog', + 'pl' : 'Przenoszenie pracy', + 'ta_IN': 'வேலைகளை பகிர்ந்து கொள்வது' }, about: { - 'en_US': 'Get comfortable with modifying the source tree', + 'en_US': '"Git" comfortable with modifying the source tree :P', 'de_DE': 'Gewöhn dich daran, den Git-Baum zu verändern', - 'fr_FR': 'Soyez alaise de modifier l\'arbre Git', + 'fr_FR': 'Soyez à l\'aise pour modifier l\'arbre Git', 'es_AR': 'Ponete cómodo con modificar el directorio fuente', + 'es_MX': 'Ponte cómodo al modificar el directorio fuente :P', + 'es_ES': 'Ponte cómodo cuando modifiques el directorio fuente', 'pt_BR': 'Fique confortável em modificar a árvore de códigos', + 'gl' : 'Ponte cómodo modificando a árbore de git', 'ko' : '작업 트리를 수정하는건 식은죽 먹기지요 이제', 'ja' : '話題のrebaseってどんなものだろう?って人にオススメ', 'zh_CN': '自由修改提交树', 'zh_TW': '自由修改提交樹', 'ru_RU': 'Не стесняйтесь менять историю', - 'uk' : 'Не соромимось змінювати історію' + 'uk' : 'Не соромимось змінювати історію', + 'vi' : 'Chỉnh sửa cây lịch sử Git không hề khó', + 'sl_SI': 'Spretno "Git" premikanje po drevesu :P', + 'pl' : 'GIT dobrze radzi sobie z modyfikacją drzewa źródłowego :P', + 'ta_IN': '"கிட்" மூல மரத்தை மாற்றுவதில் சிரந்தது :P' } }, mixed: { @@ -201,12 +272,19 @@ var sequenceInfo = exports.sequenceInfo = { 'ja' : '様々なtips', 'fr_FR': 'Un assortiment', 'es_AR': 'Bolsa de gatos', + 'es_MX': 'De todo un poco', + 'es_ES': 'Un poco de todo', 'pt_BR': 'Sortidos', + 'gl' : 'Todo mesturado', 'ko' : '종합선물세트', 'zh_CN': '杂项', 'zh_TW': '活用 git 的指令', 'ru_RU': 'Сборная солянка', - 'uk' : 'Всяке' + 'uk' : 'Всяке', + 'vi' : 'Những trò mèo đáng đồng tiền bát gạo', + 'sl_SI': 'Mešana Vreča', + 'pl' : 'Po trochu wszystkiego', + 'ta_IN': 'ஒரு கலப்பு பை' }, about: { 'en_US': 'A mixed bag of Git techniques, tricks, and tips', @@ -214,12 +292,19 @@ var sequenceInfo = exports.sequenceInfo = { 'ja' : 'gitを使う上での様々なtipsやテクニックなど', 'fr_FR': 'Un assortiment de techniques et astuces pour utiliser Git', 'es_AR': 'Un rejunte de técnicas, trucos y tips sobre Git', + 'es_MX': 'Un recopilatorio de técnicas, trucos y tips sobre Git', + 'es_ES': 'Un batiburrillo de técnicas, trucos y sugerencias sobre Git', 'pt_BR': 'Técnicas, truques e dicas sortidas sobre Git', + 'gl' : 'Mestura de técnicas, trucos e consellos', 'ko' : 'Git을 다루는 다양한 팁과 테크닉을 다양하게 알아봅니다', 'zh_CN': 'Git 技术、技巧与贴士大集合', 'zh_TW': 'git 的技術,招數與技巧', 'ru_RU': 'Ассорти из приёмов работы с Git, хитростей и советов', - 'uk' : 'Різні прийоми роботи з Git, хитрощі та поради' + 'uk' : 'Різні прийоми роботи з Git, хитрощі та поради', + 'vi' : 'Các kỹ thuật, bí quyết, và mẹo vặt hữu ích', + 'sl_SI': 'Mešana vreča Git tehnik, trikov in nasvetov', + 'pl' : 'Po trochu wszystkiego. Wskazówki i triki', + 'ta_IN': 'கிட் நுட்பங்கள், தந்திரங்கள் மற்றும் உதவிக்குறிப்புகளின் கலவையான பை' } }, advanced: { @@ -227,14 +312,21 @@ var sequenceInfo = exports.sequenceInfo = { 'en_US': 'Advanced Topics', 'de_DE': 'Themen für Fortgeschrittene', 'ja' : '上級トピック', - 'fr_FR': 'Sujets Avancés', + 'fr_FR': 'Sujets avancés', 'es_AR': 'Temas avanzados', + 'es_MX': 'Temas avanzados', + 'es_ES': 'Temas avanzados', 'pt_BR': 'Temas avançados', + 'gl' : 'Temas avanzados', 'zh_CN': '高级话题', 'zh_TW': '進階主題', 'ru_RU': 'Продвинутый уровень', 'uk' : 'Досвідчений рівень', - 'ko' : '고급 문제' + 'ko' : '고급 문제', + 'vi' : 'Các chủ đề nâng cao', + 'sl_SI': 'Napredne Teme', + 'pl' : 'Tematy zaawansowane', + 'ta_IN': 'மேம்பட்ட தலைப்புகள்' }, about: { 'en_US': 'For the truly brave!', @@ -242,12 +334,19 @@ var sequenceInfo = exports.sequenceInfo = { 'ja' : '勇気ある人のみ!', 'fr_FR': 'Pour les plus courageux !', 'es_AR': '¡Para los verdaderos valientes!', + 'es_MX': '¡Para los verdaderos valientes!', + 'es_ES': '¡Para los verdaderos valientes!', 'pt_BR': 'Para os verdadeiros valentes!', + 'gl' : '¡Para os verdadeiros valerosos!', 'zh_CN': '只为真正的勇士!', 'zh_TW': '來成為真正的強者吧!', 'ru_RU': 'Если ты смелый, ловкий, умелый – потренируйся тут', 'uk' : 'Для хоробрих', - 'ko' : '용기있는 도전자를 위해 준비한 문제입니다' + 'ko' : '용기있는 도전자를 위해 준비한 문제입니다', + 'vi' : 'Mạnh mẽ lên!', + 'sl_SI': 'Za resnično pogumne!', + 'pl' : 'Dla naprawdę odważnych!', + 'ta_IN': 'உண்மையிலேயே தைரியமானவர்களுக்கு!' } } }; diff --git a/src/levels/intro/branching.js b/src/levels/intro/branching.js index b77195ca..979a9bfc 100644 --- a/src/levels/intro/branching.js +++ b/src/levels/intro/branching.js @@ -7,25 +7,39 @@ exports.level = { "ja" : "Gitのブランチ", "ko": "Git에서 브랜치 쓰기", "es_AR": "Brancheando en Git", + "es_MX": "Creando ramas en Git", + "es_ES": "Creando ramas en Git", "pt_BR": "Ramos no Git", + "gl" : "Ramas en Git", "fr_FR": "Gérer les branches avec Git", "zh_CN": "Git Branch", "zh_TW": "建立 git branch", "ru_RU": "Ветвление в Git", - "uk": "Розгалуження в Git" + "uk": "Розгалуження в Git", + "vi": "Rẽ nhánh với Git", + "sl_SI": "Branchanje v Gitu", + "pl" : "Rozgałęzienia w GIT-cie (branch)", + "ta_IN": "கிட் கிளை நிருவாகம்" }, "hint": { "en_US": "Make a new branch with \"git branch \" and check it out with \"git checkout \"", - "de_DE": 'Lege mit "git branch " einen neuen Branch an und checke ihn mit "git checkout aus', + "de_DE": "Lege mit \"git branch [Branch-Name]\" einen neuen Branch an und checke ihn mit \"git checkout [Branch-Name]\" aus", "ja" : "ブランチの作成(\"git branch [ブランチ名]\")と、チェックアウト(\"git checkout [ブランチ名]\")", "es_AR": "Hacé una nueva rama con \"git branch [nombre]\" y cambiá a ella con \"git checkout [nombre]\"", + "es_MX": "Crea una nueva rama con \"git branch [nombre]\" y sitúate en ella con \"git checkout [nombre]\"", + "es_ES": "Crea una nueva rama con \"git branch [nombre]\" y sitúate en ella con \"git checkout [nombre]\"", "pt_BR": "Crie um novo ramo com \"git branch [nome]\" e mude para ele com \"git checkout [nome]\"", + "gl" : "Crea unha nova rama con \"git branch [nome]\" e cambiate a ela facendo \"git checkout [nome]\"", "fr_FR": "Faites une nouvelle branche avec \"git branch [nom]\" positionnez-vous dans celle-ci avec \"git checkout [nom]\"", "zh_CN": "用 'git branch <分支名>' 来创建分支,用 'git checkout <分支名>' 来切换到分支", "zh_TW": "用 'git branch [ branch 名稱]' 來建立 branch,用 'git checkout [ branch 名稱]' 切換到該 branch", "ko": "\"git branch [브랜치명]\"으로 새 브랜치를 만들고, \"git checkout [브랜치명]\"로 그 브랜치로 이동하세요", "ru_RU": "Создай новую ветку при помощи \"git branch [name]\" и перейди на неё при помощи \"git checkout [name]\"", - "uk": "Створи нову гілку за допомогою \"git branch [ім’я]\" й перейди на неї за допомогою \"git checkout [ім’я]\"" + "uk": "Створи нову гілку за допомогою \"git branch [ім’я]\" й перейди на неї за допомогою \"git checkout [ім’я]\"", + "vi": "Tạo một nhánh mới với lệnh \"git branch \" và chuyển sang đó với lệnh \"git checkout \"", + "sl_SI": "Naredi nov branch z \"git branch [ime-brancha]\" in ga checkoutaj z \"git checkout [ime-brancha]\"", + "pl" : "Utwórz nowy branch za pomocą \"git branch \" i sprawdź ją za pomocą \"git checkout \"", + "ta_IN": "இப்போது \"git branch \" கட்டளையை கொண்டு புதிய கிளை ஒன்றை உருவாக்குக பின் \"git checkout \" கொண்டு அந்த கிளைக்கு தாவுக" }, "disabledMap": { "git revert": true @@ -57,10 +71,10 @@ exports.level = { "beforeMarkdowns": [ "Let's see what branches look like in practice.", "", - "Here we will create a new branch named `newImage`" + "Here we will create a new branch named `newImage`." ], "afterMarkdowns": [ - "There, that's all there is to branching! The branch `newImage` now refers to commit `C1`" + "There, that's all there is to branching! The branch `newImage` now refers to commit `C1`." ], "command": "git branch newImage", "beforeCommand": "" @@ -70,10 +84,10 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Let's try to put some work on this new branch. Hit the button below" + "Let's try to put some work on this new branch. Hit the button below." ], "afterMarkdowns": [ - "Oh no! The `master` branch moved but the `newImage` branch didn't! That's because we weren't \"on\" the new branch, which is why the asterisk (*) was on `master`" + "Oh no! The `main` branch moved but the `newImage` branch didn't! That's because we weren't \"on\" the new branch, which is why the asterisk (*) was on `main`." ], "command": "git commit", "beforeCommand": "git branch newImage" @@ -89,15 +103,26 @@ exports.level = { "git checkout ", "```", "", - "This will put us on the new branch before committing our changes" + "This will put us on the new branch before committing our changes." ], "afterMarkdowns": [ - "There we go! Our changes were recorded on the new branch" + "There we go! Our changes were recorded on the new branch." ], "command": "git checkout newImage; git commit", "beforeCommand": "git branch newImage" } }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "*Note: In Git version 2.23, a new command called `git switch` was introduced to eventually replace `git checkout`, ", + "which is somewhat overloaded as a command (it does a bunch of separate things). The lessons here will still use ", + "`checkout` instead of `switch` because most people won't have access to `switch` yet, but support for the new command ", + "works in the app if you want to try it out! You can
learn more here.* " + ] + } + }, { "type": "ModalAlert", "options": { @@ -125,7 +150,7 @@ exports.level = { "", "Da das Anlegen von Branches keinen Plattenplatz und Speicher verbraucht, liegt es nahe die Arbeit in kleine logische Häppchen aufzuteilen, anstatt mit wenigen großen, monolithischen Branches zu hantieren.", "", - "Wir werden sehen wie Commits und Branches zusammengehören sobald wir anfangen mit beiden zu arbeiten. Bis hierhin merk dir einfach, dass ein Branch im Prinzip bedeutet \"ich möchte die Arbeit, die in diesem Commit und seinen Vorgängern steckt, sichern\"." + "Wir werden sehen wie Commits und Branches zusammengehören, sobald wir anfangen mit beiden zu arbeiten. Bis hierhin merk dir einfach, dass ein Branch im Prinzip bedeutet \"ich möchte die Arbeit, die in diesem Commit und seinen Vorgängern steckt, sichern\"." ] } }, @@ -151,7 +176,7 @@ exports.level = { "Lass uns mal ein wenig auf dem neuen Branch arbeiten. Machen wir einen Commit:" ], "afterMarkdowns": [ - "Oi! Der Branch `master` hat sich verändert, aber der Branch `issue` nicht. Das liegt daran, dass wir nicht \"auf\" dem neuen Branch waren, weshalb das Sternchen `*` auch hinter `master` steht." + "Oi! Der Branch `main` hat sich verändert, aber der Branch `issue` nicht. Das liegt daran, dass wir nicht \"auf\" dem neuen Branch waren, weshalb das Sternchen `*` auch hinter `main` steht." ], "command": "git commit", "beforeCommand": "git branch issue" @@ -228,7 +253,7 @@ exports.level = { "この新しいブランチに何か変更を加えてみましょう。次のボタンを押してください。" ], "afterMarkdowns": [ - "あらら、`newImage`ではなくて`master`ブランチが移動してしまいました。これは、私たちが`newImage`のブランチ上で作業していなかったためです。どのブランチで作業しているかは、アスタリスク(*)がついてるかどうかで分かります。" + "あらら、`newImage`ではなくて`main`ブランチが移動してしまいました。これは、私たちが`newImage`のブランチ上で作業していなかったためです。どのブランチで作業しているかは、アスタリスク(*)がついてるかどうかで分かります。" ], "command": "git commit", "beforeCommand": "git branch newImage" @@ -278,9 +303,9 @@ exports.level = { "brancheá temprano, y brancheá seguido", "```", "", - "Como no hay consumo extra de alamcenamiento ni memoria al hacer varias ramas, es más fácil dividir lógicamente tu trabajo que tener un par de ramas grandes.", + "Como no hay consumo extra de almacenamiento ni memoria al hacer varias ramas, es más fácil dividir lógicamente tu trabajo que tener un par de ramas grandes.", "", - "Cuando empecemos a mezclar ramas y commits, vamos a ver cómo se combinan estas dos herramientas. Por ahora, en cambio, simplemente recordá que una rama escencialmente dice \"Quiero incluir el trabajo de este commit y todos su ancestros\"." + "Cuando empecemos a mezclar ramas y commits, vamos a ver cómo se combinan estas dos herramientas. Por ahora, en cambio, simplemente recordá que una rama esencialmente dice \"Quiero incluir el trabajo de este commit y todos su ancestros\"." ] } }, @@ -290,10 +315,10 @@ exports.level = { "beforeMarkdowns": [ "Veamos cómo se ven las ramas en práctica.", "", - "Acá vamos a crear una rama nueva llamada `newImage`" + "Acá vamos a crear una rama nueva llamada `newImage`." ], "afterMarkdowns": [ - "Ahí está, ¡eso es todo lo que hay que hacer para branchear! La rama `newImage` ahora referencia al commit `C1`" + "Ahí está, ¡eso es todo lo que hay que hacer para branchear! La rama `newImage` ahora referencia al commit `C1`." ], "command": "git branch newImage", "beforeCommand": "" @@ -303,10 +328,10 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Pongamos algo de trabajo en esta nueva rama. Apretá el botón de acá abajo" + "Pongamos algo de trabajo en esta nueva rama. Apretá el botón de acá abajo." ], "afterMarkdowns": [ - "¡Uh, no! ¡La rama `master` avanzó, pero `newImage` no! Eso es porque no estábamos \"en\" la rama nueva, y por eso el asterisco (*) estaba en `master`" + "¡Uh, no! ¡La rama `main` avanzó, pero `newImage` no! Eso es porque no estábamos \"en\" la rama nueva, y por eso el asterisco (*) estaba en `main`." ], "command": "git commit", "beforeCommand": "git branch newImage" @@ -322,10 +347,10 @@ exports.level = { "git checkout [name]", "```", "", - "Esto va a situarnos en esa rama antes de commitear nuestros cambios" + "Esto va a situarnos en esa rama antes de commitear nuestros cambios." ], "afterMarkdowns": [ - "¡Ahí estamos! Nuestros cambios se registraron en nuestra nueva rama" + "¡Ahí estamos! Nuestros cambios se registraron en nuestra nueva rama." ], "command": "git checkout newImage; git commit", "beforeCommand": "git branch newImage" @@ -336,7 +361,163 @@ exports.level = { "options": { "markdowns": [ "¡Ok! Ya estás listo para manejar ramas. Cuando se cierre esta ventana,", - "creá una nueva rama llamada `bugFix` y cambiate a ella" + "creá una nueva rama llamada `bugFix` y cambiate a ella." + ] + } + } + ] + }, + "es_MX": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Ramas en Git", + "", + "Las ramas (branches) en Git son increíblemente livianas. Son sólo referencias a un commit específico - nada más. Por esto es que tantos entusiastas de Git siguen el mantra:", + "", + "```", + "branchea temprano, y branchea seguido", + "```", + "", + "Como no hay consumo extra de almacenamiento ni memoria al hacer varias ramas, es más fácil dividir lógicamente tu trabajo que tener un par de ramas grandes.", + "", + "Cuando empecemos a mezclar ramas y commits, vamos a ver cómo se combinan estas dos herramientas. Por ahora, en cambio, simplemente recuerda que una rama esencialmente dice \"Quiero incluir el trabajo de este commit y todos su ancestros\"." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Veamos cómo se ven las ramas en práctica.", + "", + "Acá vamos a crear una rama nueva llamada `newImage`." + ], + "afterMarkdowns": [ + "Ahí está, ¡eso es todo lo que hay que hacer para branchear! La rama `newImage` ahora referencia al commit `C1`." + ], + "command": "git branch newImage", + "beforeCommand": "" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Pongamos algo de trabajo en esta nueva rama. Aprieta el botón que se encuentra debajo." + ], + "afterMarkdowns": [ + "¡Uh, no! ¡La rama `main` avanzó, pero `newImage` no! Eso es porque no estábamos \"en\" la rama nueva, y por eso el asterisco (*) estaba en `main`." + ], + "command": "git commit", + "beforeCommand": "git branch newImage" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Digámosle a git que queremos hacer checkout a esa rama con", + "", + "```", + "git checkout [name]", + "```", + "", + "Esto nos situará en esa rama antes de hacer commit a nuestros cambios." + ], + "afterMarkdowns": [ + "¡Ahí estamos! Nuestros cambios se registraron en nuestra nueva rama." + ], + "command": "git checkout newImage; git commit", + "beforeCommand": "git branch newImage" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "¡Ok! Ya estás listo para manejar ramas. Cuando se cierre esta ventana,", + "crea una nueva rama llamada `bugFix` y cámbiate a ella." + ] + } + } + ] + }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Ramas en Git", + "", + "Las ramas (branches) en Git son increíblemente livianas. Son sólo referencias a un commit específico - nada más. Por esto es que tantos entusiastas de Git siguen el mantra:", + "", + "```", + "crea ramas al principio y hazlo también de manera frecuente", + "```", + "", + "Como no hay consumo extra de almacenamiento ni memoria al crear varias ramas, lógicamente es más fácil dividir tu trabajo que trabajar solamente con un par de ramas grandes.", + "", + "Cuando empecemos a mezclar ramas y commits, vamos a ver cómo se combinan estas dos herramientas. Por ahora, en cambio, simplemente recuerda que una rama esencialmente dice \"Quiero incluir el trabajo de este commit y todos su ancestros\"." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Veamos cómo son las ramas en la práctica.", + "", + "Ahora vamos a crear una rama nueva llamada `newImage`." + ], + "afterMarkdowns": [ + "Ahí está, ¡eso es todo lo que hay que hacer para crear una rama! La rama `newImage` ahora referencia al commit `C1`." + ], + "command": "git branch newImage", + "beforeCommand": "" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Pongamos algo de trabajo en esta nueva rama. Aprieta el botón de aquí abajo." + ], + "afterMarkdowns": [ + "¡Vaya! ¡La rama `main` avanzó, pero `newImage` no! Eso es porque no estábamos \"en\" la rama nueva, y por eso el asterisco (*) estaba en `main`." + ], + "command": "git commit", + "beforeCommand": "git branch newImage" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Digámosle a git que queremos hacer checkout a esa rama con", + "", + "```", + "git checkout [name]", + "```", + "", + "Esto va a situarnos en esa rama antes de hacer un commit con nuestros cambios." + ], + "afterMarkdowns": [ + "¡Ahí estamos! Nuestros cambios se registraron en nuestra nueva rama." + ], + "command": "git checkout newImage; git commit", + "beforeCommand": "git branch newImage" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "¡Perfecto! Ya estás listo para trabajar con ramas. Cuando se cierre esta ventana,", + "crea una nueva rama llamada `bugFix` y cámbiate a ella." ] } } @@ -368,10 +549,10 @@ exports.level = { "beforeMarkdowns": [ "Vejamos como os ramos funcionam na prática.", "", - "Aqui vamos criar um novo ramo chamado `newImage`" + "Aqui vamos criar um novo ramo chamado `newImage`." ], "afterMarkdowns": [ - "Veja, é só isso que você tem que fazer para ramificar! O ramo `newImage` agora se refere ao commit `C1`" + "Veja, é só isso que você tem que fazer para ramificar! O ramo `newImage` agora se refere ao commit `C1`." ], "command": "git branch newImage", "beforeCommand": "" @@ -381,10 +562,10 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Vamos tentar colocar algum trabalho neste novo ramo. Clique no botão abaixo" + "Vamos tentar colocar algum trabalho neste novo ramo. Clique no botão abaixo." ], "afterMarkdowns": [ - "Ah não! O ramo `master` se moveu mas o `newImage` não! Isso é porque o novo ramo não era o \"ativo\", e é por isso que o asterisco (*) estava no `master`" + "Ah não! O ramo `main` se moveu mas o `newImage` não! Isso é porque o novo ramo não era o \"ativo\", e é por isso que o asterisco (*) estava no `main`." ], "command": "git commit", "beforeCommand": "git branch newImage" @@ -400,10 +581,10 @@ exports.level = { "git checkout [nome]", "```", "", - "Isso vai nos situar no ramo antes de commitarmos nossas mudanças" + "Isso vai nos situar no ramo antes de commitarmos nossas mudanças." ], "afterMarkdowns": [ - "Aqui vamos nós! Nossas mudanças foram gravadas no novo ramo" + "Aqui vamos nós! Nossas mudanças foram gravadas no novo ramo." ], "command": "git checkout newImage; git commit", "beforeCommand": "git branch newImage" @@ -414,7 +595,89 @@ exports.level = { "options": { "markdowns": [ "Ok! Vocês estão todos prontos para ramificar. Assim que esta janela fechar,", - "crie um novo ramo chamado `bugFix` e mude para esse ramo" + "crie um novo ramo chamado `bugFix` e mude para esse ramo." + ] + } + } + ] + }, + "gl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Ramas en Git", + "", + "As Ramas en Git son tamén increiblemente liviás. Elas sinxelamente son referencias a un mesmo commit específico, e nada máis. É por iso que moitos entusiastas do Git entonan o mantra:", + "", + "```", + "ramifica cedo, ramifica sempre", + "```", + "", + "Debido a non existir sobrecarga de memoria facendo moitas ramas, é máis sinxelo dividir a lóxica do teu traballo en ramas que ter unha enorme.", + "", + "Cando comezamos a mesturar ramas e commits imos ver como eses dous recursos combínanse ben. Por agora lembra que unha rama esencialmente di \"Quero incluír o traballo deste commit e de todos os seus ancestros\"." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Vexamos cómo as ramas funcionan na práctica.", + "", + "Aquí imos crear unha nova rama chamada `newImage`." + ], + "afterMarkdowns": [ + "Mira, solo tes que poñer eso para crear unha rama! A rama `newImage` agora apunta ó commit `C1`." + ], + "command": "git branch newImage", + "beforeCommand": "" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Imos intentar colocar algún traballo nesta nova rama. Pincha no botón de abaixo." + ], + "afterMarkdowns": [ + "¡Bueno home! A rama `main` moveuse pero a rama `newImage` non! Eso é porque a nova rama non era a \"actual\", e é por iso que o asterisco (*) ficaba na rama `main`." + ], + "command": "git commit", + "beforeCommand": "git branch newImage" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Ímoslle decir a Git que nos queremos mover á rama con:", + "", + "```", + "git checkout [nome]", + "```", + "", + "Esto vainos levar á rama que tiñamos antes de facer os nosos cambios." + ], + "afterMarkdowns": [ + "¡Imos alá! Os nosos cambios foron grabados na nova rama." + ], + "command": "git checkout newImage; git commit", + "beforeCommand": "git branch newImage" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "¡Ok! Estas preparado para facer ramas. Así que podes pechar a ventá,", + "crear unha rama chamada `bugFix` e moverte para esa rama.", + "", + "Inda así, hai un atallo: se ti quixeras crear unha nova ", + "rama e moverte a ela ó mesmo tempo, ti podes escribir simplemente ", + "`git checkout -b [a-tua- rama]`." ] } } @@ -446,10 +709,10 @@ exports.level = { "beforeMarkdowns": [ "Regardons à quoi ressemblent les branches en pratique.", "", - "Nous allons nous positionner (checkout) dans une nouvelle branche appellée `newImage`" + "Nous allons nous positionner (checkout) dans une nouvelle branche appellée `newImage`." ], "afterMarkdowns": [ - "Et voilà, c'est tout ! La branche `newImage` se réfère désormais au commit `C1`" + "Et voilà, c'est tout ! La branche `newImage` se réfère désormais au commit `C1`." ], "command": "git branch newImage", "beforeCommand": "" @@ -462,7 +725,7 @@ exports.level = { "Travaillons mainenant dans cette branche. Appuyez sur le bouton ci-dessous." ], "afterMarkdowns": [ - "Oh non! La branche `master` a bougé mais pas la branche `newImage` ! C'est parce que nous n'étions pas \"sur\" la nouvelle branche, comme indiqué par l'asterisque (*) sur `master`" + "Oh non! La branche `main` a bougé mais pas la branche `newImage` ! C'est parce que nous n'étions pas \"sur\" la nouvelle branche, comme indiqué par l'astérisque (*) sur `main`." ], "command": "git commit", "beforeCommand": "git branch newImage" @@ -478,10 +741,10 @@ exports.level = { "git checkout [nom]", "```", "", - "Cela nous positionne sur la nouvelle branche avant de faire un commit avec nos modifications" + "Cela nous positionne sur la nouvelle branche avant de faire un commit avec nos modifications." ], "afterMarkdowns": [ - "C'est parti ! Nos modifications ont été enregistrées sur la nouvelle branche" + "C'est parti ! Nos modifications ont été enregistrées sur la nouvelle branche." ], "command": "git checkout newImage; git commit", "beforeCommand": "git branch newImage" @@ -492,7 +755,7 @@ exports.level = { "options": { "markdowns": [ "Ok! Vous êtes fin prêt pour faire des branches. Après la fermeture de cette fenêtre,", - "faites une nouvelle branche nommée `bugFix` et positionnez-vous sur cette branche" + "faites une nouvelle branche nommée `bugFix` et positionnez-vous sur cette branche." ] } } @@ -512,7 +775,7 @@ exports.level = { "早建分支!多用分支!", "```", "", - "这是因为即使创建再多分的支也不会造成储存或内存上的开销,并且按逻辑分解工作到不同的分支要比维护那些特别臃肿的分支简单多了。", + "这是因为即使创建再多的分支也不会造成储存或内存上的开销,并且按逻辑分解工作到不同的分支要比维护那些特别臃肿的分支简单多了。", "", "在将分支和提交记录结合起来后,我们会看到两者如何协作。现在只要记住使用分支其实就相当于在说:“我想基于这个提交以及它所有的父提交进行新的工作。”" ] @@ -541,7 +804,7 @@ exports.level = { ], "command": "git commit", "afterMarkdowns": [ - "哎呀!为什么 `master` 分支前进了,但 `newImage` 分支还待在原地呢?!这是因为我们没有“在”这个新分支上,看到 `master` 分支上的那个星号(*)了吗?这表示当前所在的分支是 `master`。" + "哎呀!为什么 `main` 分支前进了,但 `newImage` 分支还待在原地呢?!这是因为我们没有“在”这个新分支上,看到 `main` 分支上的那个星号(*)了吗?这表示当前所在的分支是 `main`。" ], "beforeCommand": "git branch newImage" } @@ -621,7 +884,7 @@ exports.level = { ], "command": "git commit", "afterMarkdowns": [ - "太奇怪了啦! `master` branch 前進了,但 `newImage` branch 沒有前進!這是因為我們沒有「在」這個新的 branch 上,這也是為什麼星號(*)會在 `master` 上。" + "太奇怪了啦! `main` branch 前進了,但 `newImage` branch 沒有前進!這是因為我們沒有「在」這個新的 branch 上,這也是為什麼星號(*)會在 `main` 上。" ], "beforeCommand": "git branch newImage" } @@ -698,7 +961,7 @@ exports.level = { "이 새로운 브랜치에 약간의 작업을 더해봅시다. 아래 버튼을 눌러주세요" ], "afterMarkdowns": [ - "앗! `master` 브랜치가 움직이고, `newImage` 브랜치는 이동하지 않았네요! 그건 우리가 새 브랜치 위에 있지 않았었기 때문입니다. 별표(*)가 `master`에 있었던 것이죠." + "앗! `main` 브랜치가 움직이고, `newImage` 브랜치는 이동하지 않았네요! 그건 우리가 새 브랜치 위에 있지 않았었기 때문입니다. 별표(*)가 `main`에 있었던 것이죠." ], "command": "git commit", "beforeCommand": "git branch newImage" @@ -750,7 +1013,7 @@ exports.level = { "", "Так как создание множества веток никак не отражается на памяти или жестком диске, удобнее и проще разбивать свою работу на много маленьких веток, чем хранить все изменения в одной огромной ветке.", "", - "Чуть позже мы попробуем использовать ветки и коммиты, и вы увидите, как две эти возможности сочетаются. Можно сказать, что созданная ветка хранит изменения текущих коммитов и всех его родителей." + "Чуть позже мы попробуем использовать ветки и коммиты, и вы увидите, как две эти возможности сочетаются. Можно сказать, что созданная ветка хранит изменения текущего коммита и всех его родителей." ] } }, @@ -760,10 +1023,10 @@ exports.level = { "beforeMarkdowns": [ "Посмотрим, что такое ветки на практике", "", - "Создадим здесь новую ветку с именем newImage" + "Создадим здесь новую ветку с именем newImage." ], "afterMarkdowns": [ - "Вот и всё, ребята! Ветка newImage теперь указывает на коммит C1" + "Вот и всё, ребята! Ветка newImage теперь указывает на коммит C1." ], "command": "git branch newImage", "beforeCommand": "" @@ -776,7 +1039,7 @@ exports.level = { "Теперь попробуем сделать некоторые изменения в этой ветке. Для этого нажми кнопку ниже." ], "afterMarkdowns": [ - "О-оу! Ветка master сдвинулась, тогда как ветка newImage - нет! Всё из-за того, что мы не переключились на новую ветку, а остались в старой, о чём говорит звёздочка около ветки master" + "О-оу! Ветка main сдвинулась, тогда как ветка newImage - нет! Всё из-за того, что мы не переключились на новую ветку, а остались в старой, о чём говорит звёздочка около ветки main." ], "command": "git commit", "beforeCommand": "git branch newImage" @@ -806,7 +1069,10 @@ exports.level = { "options": { "markdowns": [ "Ну что ж, теперь ты готов к работе с ветками. Как только это окно закроется,", - "создай ветку с именем bugFix и переключись на неё" + "создай ветку с именем bugFix и переключись на неё.", + "", + "Кстати вот тебе совет, ты можешь создать новую ветку и переключиться на неё", + "с помощью одной команды: ```git checkout -b [yourbranchname]```.", ] } } @@ -854,7 +1120,7 @@ exports.level = { "Давайте спробуємо додати якусь інформацію до цієї нової гілки. Натисни кнопку внизу." ], "afterMarkdowns": [ - "От халепа! Гілка `master` просунулася вперед, але гілка `newImage` \u2014 ні! Це тому, що ми були не \"на новій гілці\". Через це зірочка (*) була поруч з `master`." + "От халепа! Гілка `main` просунулася вперед, але гілка `newImage` \u2014 ні! Це тому, що ми були не \"на новій гілці\". Через це зірочка (*) була поруч з `main`." ], "command": "git commit", "beforeCommand": "git branch newImage" @@ -889,6 +1155,356 @@ exports.level = { } } ] + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Nhánh Git", + "", + "Nhánh trong Git cũng nhẹ đến không ngờ. Chúng chỉ đơn giản là các con trỏ đến commit -- không hơn. Đó là lý do các con chiên Git hay niệm chú:", + "", + "```", + "rẽ nhánh sớm, rẽ nhánh thường xuyên", + "```", + "", + "Bởi vì chẳng tốn bao nhiêu bộ nhớ cho việc rẽ nhánh cả, và nó dễ dàng phân chia công việc hơn là có một cái nhánh to tổ chảng.", + "", + "Khi bạn trộn lẫn commit và nhánh, bạn sẽ thấy chúng kết hợp với nhau thế nào. Còn bây giờ, đơn giản hãy nhớ nhánh cơ bản muốn nói \"Tôi muốn thành quả trong commit này và tất cả cha ông của nó\"" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Nào hãy xem nhánh trong Git hoạt động thế nào.", + "", + "Giờ chúng ta tạo một nhánh mới tên là `newImage`." + ], + "afterMarkdowns": [ + "Đó, rẽ nhánh là thế đó! Nhánh `newImage` giờ đã tham chiếu đến commit `C1`." + ], + "command": "git branch newImage", + "beforeCommand": "" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Nào cùng thử thêm nội dung vào nhánh mới này nào. Hãy bấm nút bên dưới" + ], + "afterMarkdowns": [ + "Ồ không! Nhánh `main` đã di chuyển nhưng nhánh `newImage` thì không! Đó là do ta không \"nằm trên\" nhánh mới, đó là tại sao dấu hoa thị (*) nằm trên nhánh `main`." + ], + "command": "git commit", + "beforeCommand": "git branch newImage" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Nào cùng bảo Git chuyển ta sang nhánh khác với lệnh", + "", + "```", + "git checkout ", + "```", + "", + "Lệnh này sẽ chuyển ta sang nhánh mới trước khi commit." + ], + "afterMarkdowns": [ + "Đó! Thay đổi của ta đã được lưu sang nhánh mới" + ], + "command": "git checkout newImage; git commit", + "beforeCommand": "git branch newImage" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Được rồi! Bạn đã sẵn sàng để tập rẽ nhánh rồi. Khi cửa sổ này đóng lại,", + "tạo một nhánh mới tên là `bugFix` và chuyển sang nhánh đó.", + "", + "Tiện thể, có đường tắt đấy: nếu bạn muốn tạo nhánh mới ", + "VÀ đồng thời chuyển sang luôn, bạn chỉ cần ", + "gõ `git checkout -b [yourbranchname]`." + ] + } + } + ] + }, + "sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Branches", + "", + "Tudi branchi v Gitu so izredno majhni. To so preprosto kazalci na določen commit -- nič več. Zato veliko Git navdušencev ponavlja:", + "", + "```", + "branchaj zgodaj in branchaj pogosto", + "```", + "", + "Ker ustvarjanje večih branchev ne porablja dodatnega spomina ali prostora, je lažje logično razdeliti svoje delo kot imeti velike branche.", + "", + "Ko začnemo mešati branche in commite, bomo videli kako se te dve funkcionalnosti dopolnjujeta. Za zdaj si zapomni samo to, da branch ubistvu pomeni \"Hočem vključiti delo tega commita in commite vseh njegovih staršev.\"" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Poglejmo kako branchi izgledajo v praksi.", + "", + "Tu bomo ustvarili nov branch imenovan `newImage`." + ], + "afterMarkdowns": [ + "Tako, to je vsa umetnost branchanja! Branch poimenovan `newImage` se sedaj nanaša na commit `C1`." + ], + "command": "git branch newImage", + "beforeCommand": "" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Poizkusimo dodati nekaj dela na ta nov branch. Pristisni gumb spodaj." + ], + "afterMarkdowns": [ + "O ne! `main` branch se je premaknil ampak `newImage` branch se pa ni! To je zato, ker nismo bili \"na\" novem branchu, kot smo lahko videli z označeno zvezdico (*) na `main` branchu." + ], + "command": "git commit", + "beforeCommand": "git branch newImage" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Povejmo gitu, da želimo checkoutat branch z", + "", + "```", + "git checkout ", + "```", + "", + "To nas bo postavilo na nov branch pred commitanjem sprememb." + ], + "afterMarkdowns": [ + "Tako je! Naše sprememebe so zabeležene na novem branchu." + ], + "command": "git checkout newImage; git commit", + "beforeCommand": "git branch newImage" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Ok! Pripravljen si, da začneš branchat. Ko se to okno zapre, ", + "ustvari nov branch z imenom `bugFix` in preklopi na ta branch.", + "", + "Mimogrede, tu je bližnjica: če hočeš narediti nov ", + "branch IN ga hkrati checkoutati, lahko enostavno ", + "natipkaš `git checkout -b [imeTvojegaBrancha]`." + ] + } + } + ] + }, + "pl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## GIT Branch", + "", + "Branch w GIT są niezwykle lekkie. Są po prostu wskazówkami dla konkretnego commit-u (zatwierdzenia) i to wszytko. Dlatego tak wielu entuzjastów GIT-a przestrzega Mantry:", + "", + "```", + "twórz branch-e wcześnie i często", + "```", + "", + "Ponieważ tworzenie wielu branch-y nie wiąże się z dodatkowymi kosztami przestrzeni czy też pamięci, dlatego łatwiej jest logicznie podzielić swoją pracę, niż mieć duże, mocne branch-e.", + "", + "Kiedy zaczniemy mieszać branch-e i commit-y, zobaczymy, jak łączą się te dwie funkcje. Na razie jednak pamiętaj, że branch zasadniczo mówi: \"Chcę uwzględnić pracę tego zatwierdzenia oraz wszystkie commit-y nadrzędnych\"." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Zobaczmy, jak wyglądają branch-e (gałęzie) w praktyce.", + "", + "Tutaj utworzymy nowy branch o nazwie `mojBranch`." + ], + "afterMarkdowns": [ + "To wszystko o rozgałęzieniu! Branch (gałąź) `mojBranch` odnosi się teraz do commit-u (zatwierdzenia) `C1`." + ], + "command": "git branch mojBranch", + "beforeCommand": "" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Spróbujmy trochę popracować nad tą nowym branch-em (gałęzią).\nKliknij przycisk poniżej." + ], + "afterMarkdowns": [ + "O nie! branch `main` uległ zmianie, a branch `mojBranch` nie! To dlatego, że nie byliśmy \"w\" nowym branch-u (gałęzi) i dlatego gwiazdka (*) była przy `main`" + ], + "command": "git commit", + "beforeCommand": "git branch mojBranch" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Powiedzmy GIT-owi, z którym branch-em chcemy pracować", + "", + "```", + "git checkout ", + "```", + "", + "Spowoduje to przeniesienie nas do nowego branch-a przed wprowadzeniem zmian." + ], + "afterMarkdowns": [ + "Gotowe! Nasze zmiany zostały zarejestrowane w nowym branch-u." + ], + "command": "git checkout mojBranch; git commit", + "beforeCommand": "git branch mojBranch" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "*Uwaga: w wersji 2.23 GIT-a zostało wprowadzono nowe polecenie o nazwie \n`git switch`, które zastępuje polecenie `git checkout`, ", + "a jest nieco przeciążony poleceniem (robi ono kilka oddzielnych rzeczy). Lekcje tutaj będą nadal używane", + "`checkout` zamiast `switch`, ponieważ większość ludzi nie ma jeszcze dostępu do nowego polecenia `switch`, ale w tej aplikacja obsługuje nowe polecenie, ", + "jeśli chcesz możesz ją wypróbować! Możesz dowiedzieć się więcej o poleceniu tutaj.* " + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Ok! Teraz jesteś gotowy do samodzielnego tworzenia gałęzi (branching-u).", + "Po zamknięciu tego okna, stwórz nowy branch o nazwie `bugFix` i przełącz się na ten branch.", + "", + "Przy okazji, oto skrót: jeśli chcesz stworzyć", + "nowy branch ORAZ przełączyć się na niego w tym samym czasie,", + "możesz po prostu wpisać `git checkout -b [nazwa_branch-u]`." + ] + } + } + ] + }, + "ta_IN": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## கிட் கிளைகள்", + "", + "கிட் கிளைகள் மிகவும் இலகுவானவை. அவை ஒரு குரிப்பிட்ட கமிட்டினை சுட்டி காட்டும் ஒரு இணைப்பு குறியீடு மட்டும்தான். இதனால்தான் பல கிட் ஆர்வலர்கள் உச்சரிக்கும் மந்திரம்:", + "", + "```", + "மாற்றம் செய்யும் முன்பே கிளையை உருவாக்குங்ள், அடிக்கடி தேவை என்றால் மேலும் கிளைகளை உருவாக்குங்கள்.", + "```", + "", + "ஏன் என்றால் புதிய கிளைகளை உருவாகுவது சேமிப்புபலுவோ / நினைவக மேலான்மை பலுவோ முற்றிலும் இல்லை, பெரிய பல்வேரு மற்றங்களை கொண்ட பலுமிக்க கிளைகளைக் காட்டிலும் உங்கள் வேலையை தர்க்கமாக சிரு சிரு கிளைகளக பிரிப்பது எளிது.", + "", + "கிளைகள் மற்றும் கமிட்டுகளை கொண்ட கலவை உருவாக்கும் போது இவை இரண்டின் இனக்கத்தினை விவாதிப்போம். தற்ப்போது, கிளை உருவாக்குதல் என்பதை \"இந்த கமிட்டுடன் இதர்க்கு முன் இருந்த அனைத்து கமிட்டுகளையும் தொகுக்க விரும்புகிறேன்.\" என்பதாக கருதலாம்." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "இப்போது நாம் ஒரு கிளை எப்படி இருக்கும் என்பதை பயிற்ச்சி செய்து பார்க்கலாம்.", + "", + "இங்கு `newImage` என்ற பதிய கிளை ஒன்றை உருவாக்குவோம்." + ], + "afterMarkdowns": [ + "அவ்வலவு தான், `newImage` என்ற புதிய கிளை தயாராகி விட்டது மேலும் அது `C1` என்ற கிட்டை மூலமாக குறிக்கும்படி உள்ளது." + ], + "command": "git branch newImage", + "beforeCommand": "" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "இப்போது அதில் சில மாற்றங்களை இணைப்போம். கீலே உள்ள பித்தேனை அமுக்கவும்." + ], + "afterMarkdowns": [ + "அடடா! `newImage`க்கு மாறாக `main` கிளை முன்னேறி உள்ளது! ஏன் என்றால் நாம் \"அந்த\" புதிய கிளையில் இல்ல, அதனால்தான் நட்சத்திரக் குறி (*) `main` மேலுள்ளது." + ], + "command": "git commit", + "beforeCommand": "git branch newImage" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "இப்போது நாம் கிட்டை கிளை தாவ சொல்லுவோம்.", + "", + "```", + "git checkout ", + "```", + "", + "புதிய மாற்றங்களை கமிட் செய்யும் முன்பு இது நம்மை புதிய கிளைக்கு மாற்றும்." + ], + "afterMarkdowns": [ + "அவ்வலவுதான்! நமது மாற்றங்கள் புதிய கிளையின் பதிவு செய்ய பட்டுள்ளது." + ], + "command": "git checkout newImage; git commit", + "beforeCommand": "git branch newImage" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "*குறிப்பு: கிட் 2.23 முதல், `git switch` என்ற புதிய கட்டளை `git checkout`க்கு மாற்றாக அறிமுகம் செய்ய பட்டுள்ளது, ", + "ஏன் என்றால் அது ஒரே கட்டளையில் அதிகப்படியான வேளைகளை செய்கிறது (சொல்லப்போனால் அது கொத்தாக பல தனிப்பட்ட செயல்களை செய்கின்றது). ", + "இன்னு பலர் `switch` பயன்படுத்த வழி இல்லாததால் இங்குள்ள பாடங்கள் இன்னும் `switch`க்கு பதில் `checkout` பயன்படுத்து கின்றது. ", + "இருப்பினும் இந்த செயலியில் நீங்கள் `switch`ஐ முயற்சிக்க விரும்பினால் செய்யலாம்! மேலும் விவரங்களுக்கு.* " + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "சரி! நீங்கள் இப்போது கிட் கிளை உருவாக்க தயார். இந்த திரை மூடப்பட்டவுடன்,", + "`bugFix` எனும் கிளை உருவாக்கி அந்த கிளைக்கு மாறவும்.", + "", + "சொல்லபோனால், இதற்க்கு ஒரு குறுக்குவழி உள்ளது: ஒரு புதிய கிழையை உருவாக்கி ", + "உடனெ அதற்க்கு மாற, நீங்கள்", + "`git checkout -b [yourbranchname]` என கட்டளையிட்டால் போதும்." + ] + } + } + ] } } }; diff --git a/src/levels/intro/commits.js b/src/levels/intro/commits.js index a9ee3309..fc2ece45 100644 --- a/src/levels/intro/commits.js +++ b/src/levels/intro/commits.js @@ -3,14 +3,21 @@ exports.level = { "en_US": "Introduction to Git Commits", "de_DE": "Einführung in Git Commits", "es_AR": "Introducción a los commits de Git", + "es_MX": "Introducción a los commits de Git", + "es_ES": "Introducción a los commits de Git", "pt_BR": "Introdução aos commits no Git", + "gl" : "Introducción ós commits de Git", "fr_FR": "Introduction aux commits avec Git", "ja" : "Gitのコミット", 'ko': 'Git 커밋 소개', 'zh_CN': 'Git Commit', 'zh_TW': '介紹 git commit ', 'ru_RU': 'Знакомство с Git Commit ', - 'uk': 'Знайомство з комітами в Git' + 'uk': 'Знайомство з комітами в Git', + 'vi': 'Giới thiệu về Git Commit', + 'sl_SI': "Uvod v Git Commit", + 'pl' : "Wprowadzenie do zatwierdzeń GIT-a (commit)", + "ta_IN": "கிட் கமிட்கள் ஒரு அறிமுகம்" }, "goalTreeString": "{\"branches\":{\"master\":{\"target\":\"C3\",\"id\":\"master\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C2\"],\"id\":\"C3\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}", "solutionCommand": "git commit;git commit", @@ -19,14 +26,21 @@ exports.level = { "en_US": "Just type in 'git commit' twice to finish!", "de_DE": "Gib einfach zweimal 'git commit' ein um den Level abzuschließen", "es_AR": "¡Simplemente tipeá 'git commit' dos veces para terminar!", + "es_MX": "¡Simplemente escribe 'git commit' dos veces para terminar!", + "es_ES": "¡Simplemente escribe 'git commit' dos veces para terminar!", "pt_BR": "Simplesmente digite 'git commit' duas vezes para concluir!", + "gl" : "Simplemente escribe 'git commit' dúas veces para terminar.", "fr_FR": "Il suffit de saisir 'git commit' deux fois pour réussir !", "zh_CN": "执行两次 'git commit' 就可以过关了!", "zh_TW": "輸入兩次 'git commit' 就可以完成!", "ja" : "'git commit'コマンドを2回打てば完成!", "ko": "'git commit'이라고 두 번 치세요!", "ru_RU": "Попробуй дважды выполнить команду 'git commit' ;)", - "uk": "Спробуй двічі виконати команду 'git commit' ;)" + "uk": "Спробуй двічі виконати команду 'git commit' ;)", + 'vi': "Đơn giản là cứ gõ 'git commit' 2 lần", + 'sl_SI': "Preprosto dvakrat vpiši 'git commit' in zaključi!", + "pl" : "Aby zakończyć, wystarczy dwukrotnie wpisać 'git commit'!", + "ta_IN": "இந்த நிலையை நிரைவு செய்ய 'git commit' என்று இரண்டு முறை தட்டச்சு செய்க!" }, "disabledMap": { "git revert": true @@ -39,7 +53,7 @@ exports.level = { "options": { "markdowns": [ "## Git Commits", - "A commit in a git repository records a snapshot of all the files in your directory. It's like a giant copy and paste, but even better!", + "A commit in a git repository records a snapshot of all the (tracked) files in your directory. It's like a giant copy and paste, but even better!", "", "Git wants to keep commits as lightweight as possible though, so it doesn't just blindly copy the entire directory every time you commit. It can (when possible) compress a commit as a set of changes, or a \"delta\", from one version of the repository to the next.", "", @@ -55,7 +69,7 @@ exports.level = { "beforeMarkdowns": [ "Let's see what this looks like in practice. On the right we have a visualization of a (small) git repository. There are two commits right now -- the first initial commit, `C0`, and one commit after that `C1` that might have some meaningful changes.", "", - "Hit the button below to make a new commit" + "Hit the button below to make a new commit." ], "afterMarkdowns": [ "There we go! Awesome. We just made changes to the repository and saved them as a commit. The commit we just made has a parent, `C1`, which references which commit it was based off of." @@ -68,7 +82,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Go ahead and try it out on your own! After this window closes, make two commits to complete the level" + "Go ahead and try it out on your own! After this window closes, make two commits to complete the level." ] } } @@ -81,11 +95,11 @@ exports.level = { "options": { "markdowns": [ "## Git Commits", - "Ein Commit in ein Git-Repository speichert einen Abbildung aller Dateien in deinem Projektverzeichnis. Es ist wie ein riesiges Kopieren und Einfügen, nur besser.", + "Ein Commit in einem Git-Repository speichert eine Abbildung aller Dateien in deinem Projektverzeichnis. Es ist wie ein riesiges Kopieren und Einfügen, nur besser.", "", "Allerdings will Git die Commits so schlank wie möglich halten, also kopiert es nicht einfach stur das ganze Verzeichnis jedes Mal wenn du committest. Es kann (wenn möglich) Commits als Menge von Änderungen zusammenpacken, von einer Version des Repositorys zur nächsten.", "", - "Außerdem führt Git ein Protokoll darüber welche Commits wann gemacht wurden, und welcher auf welchen folgt. Deshalb werden die Commits hier mit ihrem Vorgänger über sich gezeigt -- wir verwenden Pfeile zur Darstellung der Beziehung. Dieses Protokoll zu haben ist eine tolle Sache für jeden, der an einem Projekt arbeitet.", + "Außerdem führt Git ein Protokoll darüber, welche Commits wann gemacht wurden, und welcher auf welchen folgt. Deshalb werden die Commits hier mit ihrem Vorgänger über sich gezeigt -- wir verwenden Pfeile zur Darstellung der Beziehung. Dieses Protokoll zu haben ist eine tolle Sache für jeden, der an einem Projekt arbeitet.", "", "Das war jetzt eine Menge Neues, aber vorerst kannst du dir Commits einfach als Abbildungen des Projekts vorstellen. Commits sind sehr ressourcenschonend, und zwischen ihnen wechseln geht superschnell!" ] @@ -95,7 +109,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Mal sehen wie das in der Praxis ist. Rechts sehen wir ein (kleines) Git-Repository. Es gibt akutell zwei Commits -- den initialen, `C0`, und den danach, `C1`, der irgendwelche Änderungen enthält.", + "Mal sehen wie das in der Praxis ist. Rechts sehen wir ein (kleines) Git-Repository. Es gibt aktuell zwei Commits -- den initialen, `C0`, und den danach, `C1`, der irgendwelche Änderungen enthält.", "", "Klick die Schaltfläche unten um einen neuen Commit zu erzeugen:" ], @@ -110,7 +124,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Probier das committen gleich mal aus! Mach zwei Commits um den Level abzuschließen." + "Probier das Committen gleich mal aus! Mach zwei Commits um den Level abzuschließen." ] } } @@ -171,7 +185,7 @@ exports.level = { "## Commits de Git", "Un commit en un repositorio git registra un snapshot de todos los archivos en tu directorio. Es como un _gran_ copy&paste, ¡pero incluso mejor!", "", - "Git pretende mantener los commits tan livianos como sea posible, por lo que no copia ciegamente el directorio completo cada vez que commiteás. Puede (cuando es posible) comprimir un commit como un conjunto de cambios (o un _\"delta\"_) entre una versión de tu repositorio y la siguiente.", + "Git pretende mantener los commits tan livianos como sea posible, por lo que no copia ciegamente el directorio completo cada vez que commiteás. Puede (cuando sea posible) comprimir un commit como un conjunto de cambios (o un _\"delta\"_) entre una versión de tu repositorio y la siguiente.", "", "Git mantiene, también, un historial de qué commits se hicieron cuándo. Es por eso que la mayoría de los commits tienen commits ancestros arriba suyo -- designamos esto con flechas en nuestra visualización. ¡Mantener el historial es genial para todos los que trabajan en el proyecto!", "", @@ -185,7 +199,7 @@ exports.level = { "beforeMarkdowns": [ "Veamos cómo se ve esto en la práctica. A la derecha tenemos una visualización de un (pequeño) repositorio git. Hay dos commits ahora: el commit inicial, `C0`, y un commit que lo sigue, `C1`, que podría tener algunos cambios interesantes.", "", - "Dale al botón de abajo para hacer un nuevo commit" + "Dale al botón de abajo para hacer un nuevo commit." ], "afterMarkdowns": [ "¡Ahí va! Increíble. Acabamos de hacer cambios al repositorio y los guardamos como un commit. El commit que acabamos de crear tiene un padre, `C1`, que referencia al commit en que se basó este." @@ -204,6 +218,90 @@ exports.level = { } ] }, + "es_MX": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Commits de Git", + "Un commit en un repositorio git registra un snapshot de todos los archivos en tu directorio. Es como un _gran_ copy&paste, ¡pero incluso mejor!", + "", + "Git pretende mantener los commits tan livianos como sea posible, por lo que no copia ciegamente el directorio completo cada vez que haces commit. Puede (cuando sea posible) comprimir un commit como un conjunto de cambios (o un _\"delta\"_) entre una versión de tu repositorio y la siguiente.", + "", + "Git mantiene, también, un historial de qué commits se hicieron cuándo. Es por eso que la mayoría de los commits tienen commits ancestros arriba suyo -- designamos esto con flechas en nuestra visualización. ¡Mantener el historial es genial para todos los que trabajan en el proyecto!", + "", + "Hay un montón en lo que ahondar, pero por ahora puedes pensar en los commits como snapshots de tu proyecto. Los commits son muy livianos, y ¡cambiar de uno a otro es terriblemente rápido!" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Veamos cómo se ve esto en la práctica. A la derecha tenemos una visualización de un (pequeño) repositorio git. Hay dos commits ahora: el commit inicial, `C0`, y un commit que lo sigue, `C1`, que podría tener algunos cambios interesantes.", + "", + "Dale al botón de abajo para hacer un nuevo commit." + ], + "afterMarkdowns": [ + "¡Ahí va! Increíble. Acabamos de hacer cambios al repositorio y los guardamos como un commit. El commit que acabamos de crear tiene un padre, `C1`, que referencia al commit en que se basó este." + ], + "command": "git commit", + "beforeCommand": "" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "¡Vamos, inténtalo ahora! Cuando se cierre esta ventana, haz dos commits para completar el nivel." + ] + } + } + ] + }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Commits de Git", + "Un commit en un repositorio git registra un snapshot de todos los archivos en tu directorio. Es como un _gran_ copy&paste, ¡pero incluso mejor!", + "", + "Git pretende mantener los commits tan livianos como sea posible, por lo que no copia ciegamente el directorio completo cada vez que haces un commit. Puede (cuando es posible) comprimir un commit como un conjunto de cambios (o un _\"delta\"_) entre una versión de tu repositorio y la siguiente.", + "", + "Git mantiene, también, un historial de qué commits se hicieron y cuándo. Es por eso que la mayoría de los commits tienen commits ancestros encima -- designamos esto con flechas en nuestra visualización. ¡Mantener el historial es genial para todos los que trabajan en el proyecto!", + "", + "Hay un montón en lo que ahondar, pero por ahora puedes pensar en los commits como snapshots de tu proyecto. Los commits son muy livianos, y ¡cambiar de uno a otro es terriblemente rápido!" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Veamos cómo se ve esto en la práctica. A la derecha tenemos una visualización de un (pequeño) repositorio git. Hay dos commits: el commit inicial, `C0`, y un commit que lo sigue, `C1`, que podría tener algunos cambios interesantes.", + "", + "Dale al botón de abajo para crear un nuevo commit." + ], + "afterMarkdowns": [ + "¡Allá va! Increíble. Acabamos de hacer cambios al repositorio y los guardamos como un commit. El commit que acabamos de crear tiene un padre, `C1`, que referencia al commit en el que se basó este." + ], + "command": "git commit", + "beforeCommand": "" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "¡Venga, inténtalo ahora! Cuando se cierre esta ventana, crea dos commits para completar el nivel." + ] + } + } + ] + }, "pt_BR": { "childViews": [ { @@ -227,7 +325,7 @@ exports.level = { "beforeMarkdowns": [ "Vejamos o que isso significa na prática. À direita, temos uma visualização de um (pequeno) repositório git. Há dois commits no momento: o commit inicial, `C0`, e um commit que se segue, `C1`, que poderia conter algumas mudanças interessantes.", "", - "Clique no botão abaixo para fazer um novo commit" + "Clique no botão abaixo para fazer um novo commit." ], "afterMarkdowns": [ "Aí vamos nós! Incrível. Acabamos de fazer mudanças no repositório e as guardamos como um commit. O commit que acabamos de criar tem um pai, `C1`, que referencia em qual commit ele se baseou." @@ -246,6 +344,48 @@ exports.level = { } ] }, + "gl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Commits en Git", + "Un commit nun repositorio de git rexistra unha fotografía (snapshot) de tódolos arquivos no seu directorio. É coma un copy&paste xigante, ¡pero todavía mellor!", + "", + "Git quere gardar os commits o máis pequenos posíbel, por iso non copia directamente o directorio completo sempre que fas un commit. El pode (cando é posíbel) comprimir nun commit un conxunto de cambios (ou un _\"delta\"_) entre unha versión do teu respositorio e o seguinte.", + "", + "Git tamén garda un histórico de cando se fixo cada cambio. Por iso a maioría dos commits teñen ancestros enriba deles, e nos indicámolos con frechas na nosa visualización. ¡Manter a historia é óptimo para tódolos que traballan no proxecto!", + "", + "Hai moito que aprender, pero por agora podes pensar que os commits son fotos do teu proxecto. Os commits son liviáns, e cambiar dun para o outro é extremadamente rápido!" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Vexamos o que iso significa na práctica. Á dereita, temos unha visualización dun (pequeno) repositorio de git. Hai dous commits por agora: o commit inicial, `C0`, e un commit que lle segue, `C1`, que podería ter algúns cambios interesantes.", + "", + "Pincha no botón de abaixo para facer un novo commit." + ], + "afterMarkdowns": [ + "¡Alá imos! Mi ma!. Fixemos cambios no repositorio e gardámolos nun commit. O commit que creaches ten un pai, `C1`, que é unha referencia do commit no que se basea." + ], + "command": "git commit", + "beforeCommand": "" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Alá imos. ¡Inténtao ti agora! Cando se peche a ventá, fai dous commits para completar o nivel." + ] + } + } + ] + }, "fr_FR": { "childViews": [ { @@ -273,7 +413,7 @@ exports.level = { "beforeMarkdowns": [ "Voyons à quoi cela ressemble en pratique. Sur la droite, on peut visualiser un (petit) dépôt git. Il y a pour l'instant deux commits -- le premier commit initial, `C0`, et un commit suivant `C1` qui aurait des changements significatifs.", "", - "Appuyez sur le bouton ci-dessous pour faire un nouveau commit" + "Appuyez sur le bouton ci-dessous pour faire un nouveau commit." ], "afterMarkdowns": [ "C'est parti ! Super. Nous venons de faire des modifications sur le dépôt et de sauvegarder celles-ci dans un commit. Ce commit que nous venons de faire a un parent, `C1`, qui référence le commit sur lequel il est basé." @@ -503,6 +643,174 @@ exports.level = { } } ] + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Commits", + "Một commit trong một git repository(kho chứa) lưu trữ một ảnh chụp của tất cả các file trong thư mục của bạn. Như kiểu copy và paste cõ bự, thậm chí còn tốt hơn thế!", + "", + "Thế nhưng Git muốn giữ cho các commit nhẹ hết mức có thể, cho nên git không copy tất cả thư mục một cách mù quáng mỗi khi bạn commit. Nó có thể(khi khả dĩ) nén commit như một tập hợp các thay đổi, hay là một \"bản so sánh\", giũa một phiên bản kho chứa git với phiên bản tiếp theo.", + "", + "Đồng thời Git cũng lưu trữ lịch sử commit nào được tạo ra lúc nào. Đó là tại sao hầu hết các commit có commit tổ tiên phía trên nó -- chúng tôi đã hình tượng hóa mối quan hệ này bằng các mũi tên. Trong cộng tác nhóm thì việc gìn giữ lịch sử là rất có ích!", + "", + "Có vẻ là hơi nhiều lý thuyết rồi, bây giờ bạn chỉ cần hiều các commit là các lát cắt của dự án. Các commit rất nhẹ nên việc chuyển qua lại giữa chúng thì nhanh vô cùng!" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Thử thực hành chút nào. Ở bên phải chúng ta có mô tả một kho git (nhỏ). Hiện tại đang có 2 commit, một là commit khởi nguyên `C0`, và một commit sau đó `C1` có thể đã có một vài thay đổi.", + "", + "Bấm nút bên dưới để tạo một commit mới" + ], + "afterMarkdowns": [ + "Đúng rồi! Tuyệt vời. Bạn vừa tạo thay đổi cho kho chứa và lưu vào commit. Cái commit bạn vừa tạo nó có cha, là `C1` đấy, là commit mà nó được tạo ra từ đó." + ], + "command": "git commit", + "beforeCommand": "" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Nào bây giờ thì thử tự làm bài tập nào! Sau khi đóng cửa sổ này, tạo ra 2 commit để hoàn thành cấp độ" + ] + } + } + ] + }, + "sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Commits", + "Commit v git repozitoriju zabeleži stanje vseh datotek v tvoji mapi. Deluje kot tak velik 'Izreži in Prilepi', vendar še bolje!", + "", + "Git hoče commite ohraniti majhne kot se le da, tako da ne skopira vsakič kar vseh datotek ob commitu. Lahko (kadar je možno) stisne commit le kot množico sprememb oziroma kot \"delto\" sprememb med eno in drugo različico v repozitoriju.", + "", + "Git vodi tudi zgodovino o tem, kdaj je bil kateri commit narejen. Zato ima večina commitov nad seboj svoje prednike -- to je v vizualizaciji predstavljeno s puščicami. Vzdrževanje zgodovine je uporabno za vse, ki delajo na projektu!", + "", + "Veliko je za dojeti na začetku, ampak za zdaj si lahko predstavljaš commite kot posnetek projekta v določenem času. Commiti so zelo majhni in prehajanje med njimi je noro hitro!" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Poglejmo kako to izgleda v praksi. Na desni imamo vizualizacijo (majhnega) git repozitorija. Trenutno imamo dva commita -- prvi začetni commit, `C0`, in še en commit za tem, `C1`, ki ima lahko pomembne spremembe.", + "", + "Pritisni gumb spodaj, da narediš nov commit." + ], + "afterMarkdowns": [ + "Tako ja! Super. Pravkar smo naredili spremembe v repozitoriju in jih shranili kot commit. Commit, ki smo ga naredili ima starša, `C1`, ki nam pove iz katerega commita smo izhajali." + ], + "command": "git commit", + "beforeCommand": "" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Čas je, da poizkusiš sam! Ko se to okno zapre, naredi dva commita, da dokončaš to stopnjo." + ] + } + } + ] + }, + "pl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Zatwierdzenia GIT-a (commit)", + "`commit` w repozytorium GIT-a rejestruje migawkę wszystkich (śledzonych) plików w twoim katalogu. To jak gigantyczne kopiowanie i wklejanie, ale jeszcze lepsze!", + "", + "GIT stara się, aby commit-y były tak lekkie, jak to tylko możliwe, więc nie kopiuje na ślepo całego katalogu za każdym razem, gdy zatwierdzasz zmiany. Możesz (jeśli to możliwe) skompresować zatwierdzenie jako zestaw zmian (lub _\"delta\"_) między jedną wersją w repozytorium a następną.", + "", + "GIT przechowuje również historię, kiedy dokonano zatwierdzenia. Dlatego większość commit-ów ma na sobie zmiany przodków -- oznaczamy to strzałkami w naszej wizualizacji. Utrzymanie historii jest świetne dla wszystkich, którzy pracują nad projektem!", + "", + "Jest mnóstwo rzeczy do zagłębienia, ale na razie możesz myśleć o commit-ach jako migawkach projektu. Zatwierdzenia są bardzo lekkie, a przełączanie się między nimi jest niesamowicie szybkie!" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Zobaczmy, jak to wygląda w praktyce. Po prawej stronie mamy wizualizację (małego) repozytorium GIT-a. Istnieją dwa zatwierdzenia:\n początkowy commit `C0`, a następnie po nim commit `C1`, które mogą mieć kilka interesujących zmian.", + "", + "Kliknij poniższy przycisk, aby dokonać nowy commit." + ], + "afterMarkdowns": [ + "Gotowe! Niesamowite. Właśnie wprowadziliśmy zmiany w repozytorium i zapisaliśmy je jako zatwierdzenie (commit). Utworzony przez nas commit ma rodzica `C1`, który odnosi się do commit-a, na który został oparty." + ], + "command": "git commit", + "beforeCommand": "" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Śmiało i wypróbuj to sam! Po zamknięciu tego okna wykonaj dwa zatwierdzenia (tj. commit-y), aby ukończyć poziom." + ] + } + } + ] + }, + "ta_IN": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## கிட் கமிட்கள்", + "கிட் கமிட் உங்கள் கோப்பகத்தில் உள்ள கண்காணிக்கப்பட்ட (tracked) கோப்புகளை கிட் களஞ்சியத்தில் ஒரு நகலாக பதிவு செய்கின்றது. ஆனால் இது முழு நகல் எடுத்து ஒட்டுவதை விட சிறந்தது!", + "", + "கிட் கமிட்களை முடிந்தவரை இலகுவாக இருக்கும்படி செய்கின்றது, எனவே நீங்கள் ஒவ்வொரு முறை கமிட் செய்யும் போதும் கிட் கோப்பகங்களை கண்மூடித்தனமாக நகலெடுக்காது. அது (முடிந்தால்) கமிட்களை சுருக்கப்பட்ட மாற்றங்களின் தொகுப்பாகவோ, அல்லது களஞ்சியத்தில் ஏற்க்கனவே உள்ள பதிப்பின் \"வேறுபாட்டை\" மட்டும் கண்க்கிட்டோ சேமிக்க செயிகிறது.", + "", + "மேலும் கிட் கமிட்கள் எப்போது செய்யப்படுகிறது என்பதன் வரலாற்றையும் பராமரிக்கிறது. அதனால் தான் பெரும்பான்மையான கமிட்கள் முன்பு பதிவிட்ட கமிட்களை பின் தொடருகின்றன -- நமது வரைபடங்கள் அதனை அம்பு குறியீடுகளாக காட்டு கின்றன. வரலாற்றைப் பராமரிப்பது கணினிதிட்டத்தில் பணிபுரியும் அனைவருக்கும் உதவியாக இருக்கும்!", + "", + "புரிந்து கொள்ள நிறைய இருக்கிறது, ஆனால் இப்போதைக்கு நீங்கள் கமிட்களை திட்டத்தின் பிரதியாக நினைக்கலாம். கமிட்டுகள் மிகவும் இலகுவானவை மேலும் அவற்றுக்கிடையே மாறுவது மிகவும் எளிமையானது!" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "இது நடைமுறையில் எப்படி இருக்கும் என்று பார்ப்போம். இங்கு வலதுபுறத்தில் ஒரு (சிறிய) கிட் களஞ்சியத்தின் காட்சிப்படுத்தல் உள்ளது. இப்போது அதில் இரண்டு கமிட்கள் உள்ளன -- முதல் கமிட், `C0`, மற்றும் மேலும் இரண்டாவதாக `C1` அதில் சில பயண்னுள்ள மாற்றங்கள் இருக்கலாம்.", + "", + "புதிய கமிட் செய்ய கீழே உள்ள பொத்தானை அழுத்தவும்." + ], + "afterMarkdowns": [ + "அவ்வலவுதான்! அருமை. நாம் களஞ்சியத்தில் மாற்றங்களைச் செய்து கமிட்டாக சேமித்துள்ளோம். இப்போது செய்த கமிட்டிர்க்கு `C1` மூலமாக உள்ளது, அது அதனுடைய மூலத்தை தொடர்ந்து உள்ளது." + ], + "command": "git commit", + "beforeCommand": "" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "இப்போது இந்த திரை மூடிய பிறகு நீங்கள் முயற்சி செய்யுங்கள்!, இந்த நிலையை நிரைவு செய்ய இரண்டு கமிட்டுகள் செய்யுங்கள்." + ] + } + } + ] } } }; diff --git a/src/levels/intro/merging.js b/src/levels/intro/merging.js index 21f2be7c..064a6c37 100644 --- a/src/levels/intro/merging.js +++ b/src/levels/intro/merging.js @@ -1,31 +1,45 @@ exports.level = { "goalTreeString": "{\"branches\":{\"master\":{\"target\":\"C4\",\"id\":\"master\"},\"bugFix\":{\"target\":\"C2\",\"id\":\"bugFix\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C3\",\"C2\"],\"id\":\"C4\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}", - "solutionCommand": "git checkout -b bugFix;git commit;git checkout master;git commit;git merge bugFix", + "solutionCommand": "git checkout -b bugFix;git commit;git checkout main;git commit;git merge bugFix", "name": { "en_US": "Merging in Git", - "de_DE": "Mergen in git", + "de_DE": "Mergen in Git", "es_AR": "Mergeando en Git", + "es_MX": "Haciendo merge en Git", + "es_ES": "Haciendo merge en Git", "pt_BR": "Merge no Git", + "gl" : "Merge en Git", "fr_FR": "Faire des 'merge' (fusions de branches) avec Git", "ko": "Git에서 브랜치 합치기(Merge)", "ja"   : "ブランチとマージ", "zh_CN": "Git Merge", "zh_TW": "git 中的 merge", "ru_RU": "Слияния веток в Git", - "uk": "Злиття гілок в Git" + "uk": "Злиття гілок в Git", + "vi": "Gộp nhánh trong Git", + "sl_SI": "Merganje v Gitu", + "pl" : "Łączenie/Scalanie w GIT (merge)", + "ta_IN": "கிட்டில் இணைத்தல்" }, "hint": { - "en_US": "Remember to commit in the order specified (bugFix before master)", - "de_DE": "Denk dran in der angegebenen Reihenfolge zu committen (erst bugFix, dann master)", + "en_US": "Remember to commit in the order specified (bugFix before main)", + "de_DE": "Denk dran in der angegebenen Reihenfolge zu committen (erst bugFix, dann main)", "ja"   : "指示された順番でコミットすること(masterの前にbugFixで)", - "es_AR": "Acordate de commitear en el orden especificado (bugFix antes de master)", - "pt_BR": "Lembre-se de commitar na ordem especificada (bugFix antes de master)", - "fr_FR": "Pensez à faire des commits dans l'ordre indiqué (bugFix avant master)", - "zh_CN": "要按目标窗口中指定的顺序进行提交(bugFix 先于 master)", - "zh_TW": "記住按指定的順序 commit(bugFix 比 master 優先)", - "ko": "말씀드린 순서대로 커밋해주세요 (bugFix에 먼저 커밋하고 master에 커밋)", - "ru_RU": "Не забудь делать коммиты в правильном порядке (сначала bugFix, потом master)", - "uk": "Не забудь робити коміти в правильному порядку (спочатку bugFix, а вже потім master)" + "es_AR": "Acordate de commitear en el orden especificado (bugFix antes de main)", + "es_MX": "Acuérdate de hacer commit en el orden especificado (bugFix antes de main)", + "es_ES": "Acuérdate de hacer commit en el orden especificado (bugFix antes de main)", + "pt_BR": "Lembre-se de commitar na ordem especificada (bugFix antes de main)", + "gl" : "Lembrate de facer commit na orde específica (bugFix antes de main)", + "fr_FR": "Pensez à faire des commits dans l'ordre indiqué (bugFix avant main)", + "zh_CN": "要按目标窗口中指定的顺序进行提交(bugFix 先于 main)", + "zh_TW": "記住按指定的順序 commit(bugFix 比 main 優先)", + "ko": "말씀드린 순서대로 커밋해주세요 (bugFix에 먼저 커밋하고 main에 커밋)", + "ru_RU": "Не забудь делать коммиты в правильном порядке (сначала bugFix, потом main)", + "uk": "Не забудь робити коміти в правильному порядку (спочатку bugFix, а вже потім main)", + "vi": "Nhớ là commit theo đúng thứ tự(bugFix trước main)", + "sl_SI": 'Zapomni si, da je potrebno commitati v pravilnem vrstnem redu (bugfix pred main)', + "pl" : "Pamiętaj, aby commit-ować w określonej kolejności (bugFix przed main)", + "ta_IN": "bugFix முன் main என்ற கொடுக்கப்பட்ட வரிசையில் கட்டலை இடுவதை கருத்தில் கொள்க" }, "disabledMap": { "git revert": true @@ -43,7 +57,7 @@ exports.level = { "", "The first method to combine work that we will examine is `git merge`. Merging in Git creates a special commit that has two unique parents. A commit with two parents essentially means \"I want to include all the work from this parent over here and this one over here, *and* the set of all their parents.\"", "", - "It's easier with visuals, let's check it out in the next view" + "It's easier with visuals, let's check it out in the next view." ] } }, @@ -53,32 +67,32 @@ exports.level = { "beforeMarkdowns": [ "Here we have two branches; each has one commit that's unique. This means that neither branch includes the entire set of \"work\" in the repository that we have done. Let's fix that with merge.", "", - "We will `merge` the branch `bugFix` into `master`" + "We will `merge` the branch `bugFix` into `main`." ], "afterMarkdowns": [ - "Woah! See that? First of all, `master` now points to a commit that has two parents. If you follow the arrows up the commit tree from `master`, you will hit every commit along the way to the root. This means that `master` contains all the work in the repository now.", + "Woah! See that? First of all, `main` now points to a commit that has two parents. If you follow the arrows up the commit tree from `main`, you will hit every commit along the way to the root. This means that `main` contains all the work in the repository now.", "", "Also, see how the colors of the commits changed? To help with learning, I have included some color coordination. Each branch has a unique color. Each commit turns a color that is the blended combination of all the branches that contain that commit.", "", - "So here we see that the `master` branch color is blended into all the commits, but the `bugFix` color is not. Let's fix that..." + "So here we see that the `main` branch color is blended into all the commits, but the `bugFix` color is not. Let's fix that..." ], "command": "git merge bugFix", - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit" + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" } }, { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Let's merge `master` into `bugFix`:" + "Let's merge `main` into `bugFix`:" ], "afterMarkdowns": [ - "Since `bugFix` was an ancestor of `master`, git didn't have to do any work; it simply just moved `bugFix` to the same commit `master` was attached to.", + "Since `bugFix` was an ancestor of `main`, git didn't have to do any work; it simply just moved `bugFix` to the same commit `main` was attached to.", "", "Now all the commits are the same color, which means each branch contains all the work in the repository! Woohoo!" ], - "command": "git checkout bugFix; git merge master", - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit; git merge bugFix" + "command": "git checkout bugFix; git merge main", + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit; git merge bugFix" } }, { @@ -90,9 +104,9 @@ exports.level = { "* Make a new branch called `bugFix`", "* Checkout the `bugFix` branch with `git checkout bugFix`", "* Commit once", - "* Go back to `master` with `git checkout`", + "* Go back to `main` with `git checkout`", "* Commit another time", - "* Merge the branch `bugFix` into `master` with `git merge`", + "* Merge the branch `bugFix` into `main` with `git merge`", "", "*Remember, you can always re-display this dialog with \"objective\"!*" ] @@ -112,7 +126,7 @@ exports.level = { "", "Die einfachste Methode, mit der man Branches zusammenführen kann, ist `git merge`. Das Mergen erzeugt in git einen speziellen Commit, der zwei Vorgänger hat. Ein solcher Commit bedeutet im Prinzip \"ich möchte alle Arbeit von dem Vorgänger hier und dem dort *und* allen ihren jeweiligen Vorgängern miteinander kombinieren\".", "", - "Grafisch dargestellt ist es einfacher zu verstehen, lass es uns mal ansehen" + "Grafisch dargestellt ist es einfacher zu verstehen, lass es uns mal ansehen." ] } }, @@ -122,32 +136,32 @@ exports.level = { "beforeMarkdowns": [ "Hier haben wir zwei Branches; jeder besteht jeweils aus einem eigenen Commit. Das bedeutet, dass keiner der beiden Branches alle Inhalte des gesamten Repositorys kennt. Das werden wir mit einem Merge ändern.", "", - "Wir werden den Branch `bugFix` in `master` integrieren" + "Wir werden den Branch `bugFix` in `main` integrieren." ], "afterMarkdowns": [ - "Wow! Hast du das gesehen? Zunächst mal zeigt `master` jetzt auf einen Commit mit zwei Vorgängern. Wenn du den beiden Pfeilen immer weiter folgst, kommst du an jedem Commit im Repository vorbei. Das heißt `master` enthält jetzt alles, was es im Repository gibt.", + "Wow! Hast du das gesehen? Zunächst mal zeigt `main` jetzt auf einen Commit mit zwei Vorgängern. Wenn du den beiden Pfeilen immer weiter folgst, kommst du an jedem Commit im Repository vorbei. Das heißt `main` enthält jetzt alles, was es im Repository gibt.", "", "Siehst du außerdem wie sich die Farben der Commits verändert haben? Um die Vorgänge zu verdeutlichen hab ich etwas Farbe ins Spiel gebracht. Jeder Branch hat seine eindeutige Farbe. Jeder Merge Commit bekommt als Farbe eine Mischung aus den Farben seiner Vorgänger.", "", - "Wir sehen also, dass die Farbe des Branch `master` in alle Commits gemischt wurde, die von `bugFix` aber nicht. Ändern wir das ..." + "Wir sehen also, dass die Farbe des Branch `main` in alle Commits gemischt wurde, die von `bugFix` aber nicht. Ändern wir das ..." ], "command": "git merge bugFix", - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit" + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" } }, { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Mergen wir `master` in `bugFix`:" + "Mergen wir `main` in `bugFix`:" ], "afterMarkdowns": [ - "Da `bugFix` ein Vorgänger von `master` war, musste git hier kaum etwas tun; es verschiebt `bugFix` einfach auf den Commit, auf den auch `master` zeigt.", + "Da `bugFix` ein Vorgänger von `main` war, musste git hier kaum etwas tun; es verschiebt `bugFix` einfach auf den Commit, auf den auch `main` zeigt.", "", "Jetzt haben alle Commits dieselbe Farbe, das heißt jeder Branch enthält die Informationen des gesamten Repositorys! Juhu!" ], - "command": "git checkout bugFix; git merge master", - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit; git merge bugFix" + "command": "git checkout bugFix; git merge main", + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit; git merge bugFix" } }, { @@ -159,9 +173,9 @@ exports.level = { "* Lege einen neuen Branch `bugFix` an", "* Checke `bugFix` aus mittels `git checkout bugFix`", "* Mach einen Commit", - "* Geh mit `git checkout` zum `master` zurück", + "* Geh mit `git checkout` zum `main` zurück", "* Mach noch einen Commit", - "* Merge den Branch `bugFix` in `master` mit `git merge`", + "* Merge den Branch `bugFix` in `main` mit `git merge`", "", "*Denk dran, du kannst diese Meldung mit dem Befehl `objective` so oft anzeigen, wie du willst!*" ] @@ -191,32 +205,32 @@ exports.level = { "beforeMarkdowns": [ "それぞれ別のコミットを指している2つのブランチがあります。変更が別々のブランチに分散していて統合されていないケースです。これをマージで1つにまとめてみましょう。", "", - "`bugFix`ブランチを`master`ブランチにマージしてみます。" + "`bugFix`ブランチを`main`ブランチにマージしてみます。" ], "afterMarkdowns": [ - "わあ、見ましたか?まず初めに、`master`ブランチが2つのコミットを親に持つ新しいコミットを指してますね。`master`から親をたどっていくと、最も古いコミットにたどり着くまでに全てのコミットを含んでいる様が確認できます。これで、全ての変更を含む`master`が完成しました。", + "わあ、見ましたか?まず初めに、`main`ブランチが2つのコミットを親に持つ新しいコミットを指してますね。`main`から親をたどっていくと、最も古いコミットにたどり着くまでに全てのコミットを含んでいる様が確認できます。これで、全ての変更を含む`main`が完成しました。", "", "色がどう変わったかにも注目して下さい。学習を助けるために、ブランチ毎に色をつけています。それぞれのブランチは自分の色を持っていて、どのブランチから派生して出てくるか次第でコミットごとの色が決まります。", "", - "今回のコミットには`master`ブランチの色が使われました。しかし`bugFix`ブランチの色がまだ変わってないようなので、これを変えてみましょう。" + "今回のコミットには`main`ブランチの色が使われました。しかし`bugFix`ブランチの色がまだ変わってないようなので、これを変えてみましょう。" ], "command": "git merge bugFix", - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit" + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" } }, { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "`master`ブランチを`bugFix`ブランチにマージしてみます。" + "`main`ブランチを`bugFix`ブランチにマージしてみます。" ], "afterMarkdowns": [ - "`bugFix`ブランチは`master`ブランチの派生元だったので、gitは実際大したことはしていません。`bugFix`ブランチを指していたポインタを`master`が指していたコミットへと移動させただけです。", + "`bugFix`ブランチは`main`ブランチの派生元だったので、gitは実際大したことはしていません。`bugFix`ブランチを指していたポインタを`main`が指していたコミットへと移動させただけです。", "", "これで全てのコミットが同じ色になりました。つまり、リポジトリの中の全ての変更をそれぞれのブランチが持ったことになります。やったね!" ], - "command": "git checkout bugFix; git merge master", - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit; git merge bugFix" + "command": "git checkout bugFix; git merge main", + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit; git merge bugFix" } }, { @@ -228,9 +242,9 @@ exports.level = { "* `bugFix`という名前で新しいブランチを切る", "* `git checkout bugFix`コマンドで`bugFix`ブランチに切り替える", "* 一回だけコミット", - "* `git checkout`で`master`へ戻る", + "* `git checkout`で`main`へ戻る", "* もう1回コミットする", - "* `git merge`コマンドを使って、`bugFix`ブランチを`master`ブランチへとマージする", + "* `git merge`コマンドを使って、`bugFix`ブランチを`main`ブランチへとマージする", "", "*注:\"objective\"コマンドでこのヘルプにいつでも戻ってこれます*" ] @@ -248,7 +262,7 @@ exports.level = { "", "¡Genial! Ya sabemos cómo commitear y cómo crear ramas. Ahora tenemos que aprender algún modo de unificar el trabajo de dos ramas diferentes. Esto nos va a permitir abrir una nueva rama de desarrollo, implementar alguna nueva funcionalidad, y después unirla de nuevo con el trabajo principal.", "", - "El primer método para combinarlas que vamos a explorar es `git merge`. Mergear en Git crea un commit especial que tiene dos padres diferentes. Un commit con dos padres escencialmente significa \"Quiero incluir todo el trabajo de este padre de acá y este otro padre de acá, *y* del conjunto de todos sus ancestros\"", + "El primer método para combinarlas que vamos a explorar es `git merge`. Mergear en Git crea un commit especial que tiene dos padres diferentes. Un commit con dos padres esencialmente significa \"Quiero incluir todo el trabajo de este padre de acá y este otro padre de acá, *y* del conjunto de todos sus ancestros\"", "", "Es más simple visualizarlo, veámoslo a continuación" ] @@ -260,32 +274,32 @@ exports.level = { "beforeMarkdowns": [ "Acá tenemos dos ramas, y cada una tiene un commit que le es único. Esto significa que ninguna de las ramas incluye \"todo el trabajo\" que hay en nuestro repositorio. Hagamos un merge para solucionar eso.", "", - "Vamos a `merge`ar la rama `bugFix` a `master`" + "Vamos a `merge`ar la rama `bugFix` a `main`." ], "afterMarkdowns": [ - "¡Wooow! ¿Viste eso? Primero que nada, `master` ahora apunta a un commit que tiene dos padres. Si seguís las flechas por el árbol de commits empezando desde `master` vas a cruzarte con cada commit del repositorio hasta llegar a la raíz. Esto significa que `master` ahora contiene todo el trabajo que hay en el repositorio.", + "¡Wooow! ¿Viste eso? Primero que nada, `main` ahora apunta a un commit que tiene dos padres. Si seguís las flechas por el árbol de commits empezando desde `main` vas a cruzarte con cada commit del repositorio hasta llegar a la raíz. Esto significa que `main` ahora contiene todo el trabajo que hay en el repositorio.", "", "Además, ¿viste cómo cambiaron los colores de los commits? Para ayudar al aprendizaje, incluí algunas convenciones de colores. Cada rama tiene un color propio. Cada commmit se vuelve del color resultante de mezclar los colores de todas las ramas que lo contienen.", "", - "Así que acá vemos que el color de la rama `master` participa en la mezcla de todos los commits, pero que el de `bugFix` no. Arreglemos eso..." + "Así que acá vemos que el color de la rama `main` participa en la mezcla de todos los commits, pero que el de `bugFix` no. Arreglemos eso..." ], "command": "git merge bugFix", - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit" + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" } }, { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Mergeemos `master` a `bugFix`:" + "Mergeemos `main` a `bugFix`:" ], "afterMarkdowns": [ - "Como `bugFix` era un ancestro de `master`, git no tuvo que hacer ningún trabajo; simplemente movió `bugFix` al mismo commit al que estaba anexado `master`.", + "Como `bugFix` era un ancestro de `main`, git no tuvo que hacer ningún trabajo; simplemente movió `bugFix` al mismo commit al que estaba anexado `main`.", "", "Ahora todos los commits son del mismo color, lo que significa que cada rama contiene todo el trabajo que hay en el repositorio. ¡Wiii!" ], - "command": "git checkout bugFix; git merge master", - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit; git merge bugFix" + "command": "git checkout bugFix; git merge main", + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit; git merge bugFix" } }, { @@ -297,9 +311,9 @@ exports.level = { "* Creá una nueva rama, llamada `bugFix`", "* Checkouteá la rama `bugFix` usando `git checkout bugFix`", "* Hacé un commit", - "* Volvé a `master` con `git checkout`", + "* Volvé a `main` con `git checkout`", "* Hacé otro commit", - "* Mergeá la rama `bugFix` a `master` usando `git merge`", + "* Mergeá la rama `bugFix` a `main` usando `git merge`", "", "*Acordate: siempre podés volver a ver este mensaje tipeando \"objective\"!*" ] @@ -307,6 +321,144 @@ exports.level = { } ] }, + "es_MX": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Mergeando ramas", + "", + "¡Genial! Ya sabemos cómo hacer commit y cómo crear ramas. Ahora tenemos que aprender algún modo de unificar el trabajo de dos ramas diferentes. Esto nos va a permitir abrir una nueva rama de desarrollo, implementar alguna nueva funcionalidad, y después unirla de nuevo con el trabajo principal.", + "", + "El primer método para combinarlas que vamos a explorar es `git merge`. Mergear en Git crea un commit especial que tiene dos padres diferentes. Un commit con dos padres esencialmente significa \"Quiero incluir todo el trabajo de este padre de acá y este otro padre de acá, *y* del conjunto de todos sus ancestros\"", + "", + "Es más simple visualizarlo, veámoslo a continuación" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Acá tenemos dos ramas, y cada una tiene un commit que le es único. Esto significa que ninguna de las ramas incluye \"todo el trabajo\" que hay en nuestro repositorio. Hagamos un merge para solucionar eso.", + "", + "Vamos a `merge`ar la rama `bugFix` a `main`." + ], + "afterMarkdowns": [ + "¡Wooow! ¿Viste eso? Primero que nada, `main` ahora apunta a un commit que tiene dos padres. Si sigues las flechas por el árbol de commits empezando desde `main` vas a cruzarte con cada commit del repositorio hasta llegar a la raíz. Esto significa que `main` ahora contiene todo el trabajo que hay en el repositorio.", + "", + "Además, ¿Viste cómo cambiaron los colores de los commits? Para ayudar al aprendizaje, incluí algunas convenciones de colores. Cada rama tiene un color propio. Cada commmit se vuelve del color resultante de mezclar los colores de todas las ramas que lo contienen.", + "", + "Así que acá vemos que el color de la rama `main` participa en la mezcla de todos los commits, pero que el de `bugFix` no. Arreglemos eso..." + ], + "command": "git merge bugFix", + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Mergeemos `main` a `bugFix`:" + ], + "afterMarkdowns": [ + "Como `bugFix` era un ancestro de `main`, git no tuvo que hacer ningún trabajo; simplemente movió `bugFix` al mismo commit al que estaba anexado `main`.", + "", + "Ahora todos los commits son del mismo color, lo que significa que cada rama contiene todo el trabajo que hay en el repositorio. ¡Súper!" + ], + "command": "git checkout bugFix; git merge main", + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit; git merge bugFix" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para completar este nivel, sigue estos pasos:", + "", + "* Crea una nueva rama, llamada `bugFix`", + "* Cambia a la rama `bugFix` usando `git checkout bugFix`", + "* Haz un commit", + "* Vuelve a `main` con `git checkout`", + "* Haz otro commit", + "* Haz un merge de la rama `bugFix` a `main` usando `git merge`", + "", + "*Recuerda: siempre puedes volver a ver este mensaje usando el comando \"objective\"!*" + ] + } + } + ] + }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Haciendo merge en ramas", + "", + "¡Genial! Ya sabemos cómo crear un commit y cómo crear ramas. Ahora tenemos que aprender algún modo de unificar el trabajo de dos ramas diferentes. Esto nos va a permitir abrir una nueva rama de desarrollo, implementar alguna nueva funcionalidad, y después unirla de nuevo con el trabajo principal.", + "", + "El primer método para combinarlas que vamos a explorar es `git merge`. Hacer merge en Git crea un commit especial que tiene dos padres diferentes. Un commit con dos padres escencialmente significa \"Quiero incluir todo el trabajo de estos dos padres , *y* del conjunto de todos sus ancestros\"", + "", + "Es más simple visualizarlo, veámoslo a continuación" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Aquí tenemos dos ramas, y cada una tiene un commit que le es único. Esto significa que ninguna de las ramas incluye \"todo el trabajo\" que hay en nuestro repositorio. Hagamos un merge para solucionar eso.", + "", + "Vamos a `merge`ar la rama `bugFix` a `main`." + ], + "afterMarkdowns": [ + "¡Caramba! ¿Viste eso? Antes de nada, `main` ahora apunta a un commit que tiene dos padres. Si sigues las flechas por el árbol de commits empezando desde `main` vas a cruzarte con cada commit del repositorio hasta llegar a la raíz. Esto significa que `main` ahora contiene todo el trabajo que hay en el repositorio.", + "", + "Además, ¿viste cómo cambiaron los colores de los commits? Para ayudar al aprendizaje, he incluido algunas convenciones de colores. Cada rama tiene un color propio. Cada commmit se vuelve del color resultante de mezclar los colores de todas las ramas que lo contienen.", + "", + "Así que aquí vemos que el color de la rama `main` participa en la mezcla de todos los commits, pero que el de `bugFix` no. Arreglemos eso..." + ], + "command": "git merge bugFix", + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Hagamos merge de `main` a `bugFix`:" + ], + "afterMarkdowns": [ + "Como `bugFix` era un ancestro de `main`, git no tuvo que hacer ningún trabajo; simplemente movió `bugFix` al mismo commit al que estaba anexado `main`.", + "", + "Ahora todos los commits son del mismo color, lo que significa que cada rama contiene todo el trabajo que hay en el repositorio. ¡Genial!" + ], + "command": "git checkout bugFix; git merge main", + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit; git merge bugFix" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para completar este nivel, sigue estos pasos:", + "", + "* Crea una nueva rama, llamada `bugFix`", + "* Haz checkout de la rama `bugFix` usando `git checkout bugFix`", + "* Crea un commit", + "* Vuelve a `main` con `git checkout`", + "* Crea otro commit", + "* Haz merge de la rama `bugFix` a `main` usando `git merge`", + "", + "*Recuerda: siempre puedes volver a ver este mensaje escribiendo \"objective\"!*" + ] + } + } + ] + }, "pt_BR": { "childViews": [ { @@ -319,7 +471,7 @@ exports.level = { "", "O primeiro método para combinar trabalho que vamos examinar é o `git merge`. O merge do Git cria um commit especial que possui dois pais únicos. Um commit com dois pais essencialmente significa \"Quero incluir todo o trabalho deste pai aqui com o daquele outro pai ali, *e* com o do conjunto de todos os seus ancestrais.\"", "", - "É mais fácil com uma visualização, vamos ver logo a seguir" + "É mais fácil com uma visualização, vamos ver logo a seguir." ] } }, @@ -329,32 +481,32 @@ exports.level = { "beforeMarkdowns": [ "Aqui nós temos dois ramos; cada um tem um commit que é único. Isso significa que nenhum ramo inclui o conjunto do \"trabalho\" que foi realizado no repositório. Vamos consertar isso com um merge.", "", - "Vamos juntar o ramo `bugFix` no `master`" + "Vamos juntar o ramo `bugFix` no `main`." ], "afterMarkdowns": [ - "Uau! Viu isso? Antes de tudo, o `master` agora aponta para um commit que possui dois pais. Se você seguir as setas subindo a árvore de commits a partir do `master`, você será capaz de encontrar, ao longo do caminho até a raiz, qualquer um dos commits. Isso significa que o `master` contém todo o trabalho realizado no repositório até o momento.", + "Uau! Viu isso? Antes de tudo, o `main` agora aponta para um commit que possui dois pais. Se você seguir as setas subindo a árvore de commits a partir do `main`, você será capaz de encontrar, ao longo do caminho até a raiz, qualquer um dos commits. Isso significa que o `main` contém todo o trabalho realizado no repositório até o momento.", "", "Além disso, viu como as cores dos commits mudaram? Para ajudá-lo a aprender, eu incluí uma legenda. Cada ramo tem uma cor única. Cada commit tem a cor resultante da mistura das cores de todos os ramos que o contém.", "", - "Aqui vemos que a cor do ramo `master` está misturada em todos os commits, mas a cor do `bugFix` não está. Vamos corrigir isso..." + "Aqui vemos que a cor do ramo `main` está misturada em todos os commits, mas a cor do `bugFix` não está. Vamos corrigir isso..." ], "command": "git merge bugFix", - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit" + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" } }, { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Vamos juntar o `master` no `bugFix`:" + "Vamos juntar o `main` no `bugFix`:" ], "afterMarkdowns": [ - "Como o `bugFix` é um ancestral do `master`, o git não teve trabalho nenhum; ele só precisou mover o `bugFix` para o mesmo commit do `master`.", + "Como o `bugFix` é um ancestral do `main`, o git não teve trabalho nenhum; ele só precisou mover o `bugFix` para o mesmo commit do `main`.", "", "Agora todos os commits possuem a mesma cor, o que significa que ambos os ramos contém todo o trabalho realizado no repositório! Eba!" ], - "command": "git checkout bugFix; git merge master", - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit; git merge bugFix" + "command": "git checkout bugFix; git merge main", + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit; git merge bugFix" } }, { @@ -366,9 +518,9 @@ exports.level = { "* Crie um novo ramo chamado `bugFix`", "* Faça checkout no ramo `bugFix` com `git checkout bugFix`", "* Faça um commit", - "* Volte ao `master` com `git checkout`", + "* Volte ao `main` com `git checkout`", "* Faça um novo commit", - "* Junte o ramo `bugFix` no `master` com `git merge`", + "* Junte o ramo `bugFix` no `main` com `git merge`", "", "*Lembre-se, você pode sempre mostrar esta mensagem novamente com o comando \"objective\"!*" ] @@ -376,6 +528,75 @@ exports.level = { } ] }, + "gl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Ramas e merges", + "", + "¡Xenial! Agora sabemos como facer commits e crear ramas. Agora precisamos aprender unha forma de combinar o traballo de dúas ramas diferentes. Iso permitiríanos ramificar, facer un novo cambio, e entón mesturalo de volta.", + "", + "O primeiro comando para mesturar o traballo que imos ver é `git merge`. O merge de Git crea un commit especial que ten dous pais únicos. Un commit con dous pais significa \"Quero incluír todo o traballo deste pai cos cambios do outro pai, *e* o conxunto de tódolos ancestros.\"", + "", + "É máis doado con unha visualización, ímolo ver na seguinte vista." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Aquí nos temos dúas ramas; cada unha ten un commit que é único. Isto significa que ningunha rama inclúe o conxunto de \"traballo\" feito no noso repositorio. Imos arranxar esto cun merge.", + "", + "Imos xuntar a rama `bugFix` na `main`." + ], + "afterMarkdowns": [ + "¡Uah! ¿Viches? Antes de todo, `main` agora apunta a un commit que ten dous pais. Se ti sigues as frechas subindo a árbore de commits a partir de `main`, serás capaz de ver tódolos commits ata a raíz, calquera de eles. Isto significa que a rama `main` contén todo o traballo realizado no repositorio ata ese momento.", + "", + "Ademáis, ¿viches como cambiaron as cores dos commits? Para axudarte a aprender, hai unha lenda. Cada rama ten unha única cor. Cada commit ten a cor resultante de mesturar as cores de tódalas ramas que contén.", + "", + "Aquí vemos que a rama `main` está mesturada en todos os commits, pero a cor da rama `bugFix` non o está. Imos arranxar eso..." + ], + "command": "git merge bugFix", + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Imos mesturar a rama `main` en `bugFix`:" + ], + "afterMarkdowns": [ + "Como o `bugFix` é un ancestro de `main`, o git non ten traballo que facer; el só ten que mover o punteiro de `bugFix` para o mesmo commit que `main`.", + "", + "Agora tódolos commits teñen a mesma cor, o que significa que ambas ramas teñen o mesmo traballo no repositorios! Iepa!" + ], + "command": "git checkout bugFix; git merge main", + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit; git merge bugFix" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para completar este nivel, fai o seguinte:", + "", + "* Crea unha nova ramara chamada `bugFix`", + "* Fai checkout da rama `bugFix` con `git checkout bugFix`", + "* Fai un commit", + "* Volve á rama `main` con `git checkout`", + "* Fai un novo commit", + "* Xunta a rama `bugFix` en `main` con `git merge`", + "", + "¡Recorda, podes amosar esta mensaxe novamente co comando \"objective\"!" + ] + } + } + ] + }, "fr_FR": { "childViews": [ { @@ -384,11 +605,11 @@ exports.level = { "markdowns": [ "## Branches et Merges", "", - "Super ! Nous savons désormais comment faire des commits et des branches. Maintenant nous devons apprendre comment combiner ensemble les contenus de deux branches différentes. Ceci nous permettra de créer une nouvelle branche, développer une nouvelle fonctionnalité sur cette dernière, puis intégrer cette fonctionnalité en combinant le contenu de cette branche de développement à la branche d'origine(master par exemple).", + "Super ! Nous savons désormais comment faire des commits et des branches. Maintenant nous devons apprendre comment combiner ensemble les contenus de deux branches différentes. Ceci nous permettra de créer une nouvelle branche, développer une nouvelle fonctionnalité sur cette dernière, puis intégrer cette fonctionnalité en combinant le contenu de cette branche de développement à la branche d'origine (main par exemple).", "", "La première méthode que nous allons voir pour combiner le contenu de deux branches est `git merge`. Faire un 'merge' avec Git crée un commit spécial qui a deux parents. Un commit avec deux parents indique en susbtance \"Je veux inclure le contenu de ce parent et le contenu de cet autre parent, *et* l'ensemble de leurs parents.\"", "", - "C'est plus facile en visualisant, regardons dans la vue suivante" + "C'est plus facile en visualisant, regardons dans la vue suivante." ] } }, @@ -398,32 +619,32 @@ exports.level = { "beforeMarkdowns": [ "Ici nous avons deux branches ; chacune a un commit qui lui est propre. Cela signifie qu'aucune des deux branches n'inclut la totalité du \"travail\" qui a été fait dans le dépôt. Arrangeons-cela avec merge.", "", - "Nous allons `merge` («fusionner») la branche `bugFix` dans `master`" + "Nous allons `merge` («fusionner») la branche `bugFix` dans `main`." ], "afterMarkdowns": [ - "Youhou ! Vous avez vu ça ? Avant tout, `master` pointe donc maintenant sur un commit qui a deux parents. Si vous remontez l'enchaînement des flèches depuis `master`, vous allez passez par tous les commits jusqu'à la racine. Cela signifie que `master` contient maintenant tout le travail du dépôt.", + "Youhou ! Vous avez vu ça ? Avant tout, `main` pointe donc maintenant sur un commit qui a deux parents. Si vous remontez l'enchaînement des flèches depuis `main`, vous allez passez par tous les commits jusqu'à la racine. Cela signifie que `main` contient maintenant tout le travail du dépôt.", "", "Par ailleurs, avez-vous remarqué les nouvelles couleurs des commits ? Pour faciliter l'apprentissage, j'ai inclus une certaine logique dans la coloration. Chaque branche a une unique couleur. Chaque commit est de la couleur de toutes les branches qui le contiennent.", "", - "Ici nous voyons que la couleur de `master` est intégrée à tous les commits, sauf ceux de `bugFix`. Réparons-cela ..." + "Ici nous voyons que la couleur de `main` est intégrée à tous les commits, sauf ceux de `bugFix`. Réparons-cela ..." ], "command": "git merge bugFix", - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit" + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" } }, { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Faisons un merge de `master` dans `bugFix`:" + "Faisons un merge de `main` dans `bugFix`:" ], "afterMarkdowns": [ - "Puisque `bugFix` était un descendant de `master`, git n'avait aucun travail à effectuer ; il a simplement déplacé `bugFix` au même commit auquel `master` est attaché.", + "Puisque `bugFix` était un ancêtre de `main`, git n'avait aucun travail à effectuer; il a simplement déplacé `bugFix` au même commit auquel `main` est attaché.", "", "Maintenant tous les commits sont de la même couleur, ce qui indique que chaque branche contient tout le contenu du dépôt ! Woohoo!" ], - "command": "git checkout bugFix; git merge master", - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit; git merge bugFix" + "command": "git checkout bugFix; git merge main", + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit; git merge bugFix" } }, { @@ -435,9 +656,9 @@ exports.level = { "* Faites une nouvelle branche appelée `bugFix`", "* Positionnez-vous sur la branche `bugFix` avec `git checkout bugFix`", "* Faites un commit", - "* Retournez sur la branche `master` (commande `git checkout`)", + "* Retournez sur la branche `main` (commande `git checkout`)", "* Faites un nouveau commit", - "* Fusionnez la branche `bugFix` dans `master` avec `git merge`", + "* Fusionnez la branche `bugFix` dans `main` avec `git merge`", "", "*Rappelez-vous que vous pouvez à tout moment réafficher ces indications avec \"objective\"!*" ] @@ -467,32 +688,32 @@ exports.level = { "beforeMarkdowns": [ "我们准备了两个分支,每个分支上各有一个独有的提交。这意味着没有一个分支包含了我们修改的所有内容。咱们通过合并这两个分支来解决这个问题。", "", - "我们要把 `bugFix` 合并到 `master` 里" + "我们要把 `bugFix` 合并到 `main` 里" ], "command": "git merge bugFix", "afterMarkdowns": [ - "哇哦!看见了吗?首先,`master` 现在指向了一个拥有两个父节点的提交记录。假如从 `master` 开始沿着箭头向上看,在到达起点的路上会经过所有的提交记录。这意味着 `master` 包含了对代码库的所有修改。↓↓↓", + "哇哦!看见了吗?首先,`main` 现在指向了一个拥有两个父节点的提交记录。假如从 `main` 开始沿着箭头向上看,在到达起点的路上会经过所有的提交记录。这意味着 `main` 包含了对代码库的所有修改。↓↓↓", "", "还有,看见各个提交记录的颜色变化了吗?为了帮助学习理解,我引入了颜色搭配。每个分支都有不同的颜色,而每个提交记录的颜色是所有包含该提交记录的分支的颜色混合之后的颜色。", "", - "所以,`master` 分支的颜色被混入到所有的提交记录,但 `bugFix` 没有。下面咱们让它也改变一下颜色。" + "所以,`main` 分支的颜色被混入到所有的提交记录,但 `bugFix` 没有。下面咱们让它也改变一下颜色。" ], - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit" + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" } }, { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "咱们再把 `master` 分支合并到 `bugFix`:" + "咱们再把 `main` 分支合并到 `bugFix`:" ], - "command": "git checkout bugFix; git merge master", + "command": "git checkout bugFix; git merge main", "afterMarkdowns": [ - "因为 `master` 继承自 `bugFix`,Git 什么都不用做,只是简单地把 `bugFix` 移动到 `master` 所指向的那个提交记录。", + "因为 `main` 继承自 `bugFix`,Git 什么都不用做,只是简单地把 `bugFix` 移动到 `main` 所指向的那个提交记录。", "", "现在所有提交记录的颜色都一样了,这表明每一个分支都包含了代码库的所有修改!大功告成!" ], - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit; git merge bugFix" + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit; git merge bugFix" } }, { @@ -504,9 +725,9 @@ exports.level = { "* 创建新分支 `bugFix`", "* 用 `git checkout bugFix` 命令切换到该分支", "* 提交一次", - "* 用 `git checkout master` 切换回 `master`", + "* 用 `git checkout main` 切换回 `main`", "* 再提交一次", - "* 用 `git merge` 把 `bugFix` 合并到 `master`", + "* 用 `git merge` 把 `bugFix` 合并到 `main`", "", "* 你随时都可以用“objective”命令来打开这个对话框!*" ] @@ -522,7 +743,7 @@ exports.level = { "markdowns": [ "## branch 以及 merge", "", - "太好了! 我們已經知道怎麼使用 commit 和 branch 了。接下來要學的一招是如何合併(merge)兩個不同 branch 的工作。這讓我們可以建立一個新的 branch ,並且在上面開發新功能,然後合併回 master branch。", + "太好了! 我們已經知道怎麼使用 commit 和 branch 了。接下來要學的一招是如何合併(merge)兩個不同 branch 的工作。這讓我們可以建立一個新的 branch ,並且在上面開發新功能,然後合併回 main branch。", "", "`git merge` 是我們要學習 merge 的第一個方法。該 merge 會產生一個特殊的 commit,它包含兩個唯一 parent commit。一個 commit 如果有兩個 parent commit 的話,那就表示:「我想把這兩個 parent commit 本身及它們的 所有的 parent commit 都包含進來。」", "", @@ -536,32 +757,32 @@ exports.level = { "beforeMarkdowns": [ "在這裡,我們有兩個 branch:各自都有一個唯一的 commit。這意味著沒有一個 branch 包含我們對文件的所有修改。讓我們 merge 這兩個 branch 來解決這個問題。", "", - "我們要 merge `bugFix` 到 `master` " + "我們要 merge `bugFix` 到 `main` " ], "command": "git merge bugFix", "afterMarkdowns": [ - "哇!看見了沒有?首先,`master` 現在指向一個 commit,這個 commit 有兩個 parent commit。假如從 `master` 開始沿著箭頭向上走,在到達起點的路上會經過所有的 commit。這說明了現在 `master` 紀錄了對文件的所有修改。", + "哇!看見了沒有?首先,`main` 現在指向一個 commit,這個 commit 有兩個 parent commit。假如從 `main` 開始沿著箭頭向上走,在到達起點的路上會經過所有的 commit。這說明了現在 `main` 紀錄了對文件的所有修改。", "", "還有,看見各個 commit 的顏色變化了嗎?為了幫助學習,我混合了顏色。每個 branch 都有特定的顏色。每個 commit 的顏色都變成了含有此 commit 的所有 branch 的混合色。", "", - "所以,`master` branch 的顏色被混入到所有的 commit,但 `bugFix` 沒有。接下來就改一下這裡吧。" + "所以,`main` branch 的顏色被混入到所有的 commit,但 `bugFix` 沒有。接下來就改一下這裡吧。" ], - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit" + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" } }, { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "讓我們 merge `master` branch 到 `bugFix` 吧。" + "讓我們 merge `main` branch 到 `bugFix` 吧。" ], - "command": "git checkout bugFix; git merge master", + "command": "git checkout bugFix; git merge main", "afterMarkdowns": [ - "因為 `bugFix` branch只是 `master` branch 的 parent,git 什麼都不用做,只是簡單地把 `bugfix` branch 移動到 `master` 指向的 commit。", + "因為 `bugFix` branch只是 `main` branch 的 parent,git 什麼都不用做,只是簡單地把 `bugfix` branch 移動到 `main` 指向的 commit。", "", "現在所有的 commit 的顏色都是一樣的啦,這表示每一個 branch 都包含了所有文件的修改!太厲害了啦!" ], - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit; git merge bugFix" + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit; git merge bugFix" } }, { @@ -573,9 +794,9 @@ exports.level = { "* 建立新的 branch,叫做 `bugFix` ", "* 用 `git checkout bugFix` 切換到 `bugFix` branch", "* commit 一次", - "* 用 `git checkout` 切換回 `master` branch", + "* 用 `git checkout` 切換回 `main` branch", "* 再 commit 一次", - "* 用 `git merge` 將 `bugFix` merge 到 `master`", + "* 用 `git merge` 將 `bugFix` merge 到 `main`", "", "*記住,你可以用 \"objective\" 指令來重新顯示這個對話框!*" ] @@ -605,32 +826,32 @@ exports.level = { "beforeMarkdowns": [ "여기에 브랜치가 두 개 있습니다. 각 브랜치에 독립된 커밋이 하나씩 있구요. 그 말은 이 저장소에 지금까지 작업한 내역이 나뉘어 담겨 있다는 얘기입니다. 두 브랜치를 합쳐서(merge) 이 문제를 해결해 볼까요?", "", - "`bugFix` 브랜치를 `master` 브랜치에 합쳐(merge) 보겠습니다." + "`bugFix` 브랜치를 `main` 브랜치에 합쳐(merge) 보겠습니다." ], "afterMarkdowns": [ - "보셨어요? 우선, `master`가 두 부모가 있는 커밋을 가리키고 있습니다. ", + "보셨어요? 우선, `main`가 두 부모가 있는 커밋을 가리키고 있습니다. ", "", "또, 커밋들의 색이 바뀐 것을 눈치 채셨나요? 이해를 돕기위해 색상으로 구분해 표현했습니다. 각 브랜치는 그 브랜치만의 색상으로 그렸습니다. 브랜치가 합쳐지는 커밋의 경우에는, 그 브랜치들의 색을 조합한 색상으로 표시 했습니다.", "", - "그런식으로 여기에 `bugFix`브랜치 쪽을 제외한 나머지 커밋만 `master` 브랜치의 색으로 칠해져 있습니다. 이걸 고쳐보죠..." + "그런식으로 여기에 `bugFix`브랜치 쪽을 제외한 나머지 커밋만 `main` 브랜치의 색으로 칠해져 있습니다. 이걸 고쳐보죠..." ], "command": "git merge bugFix", - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit" + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" } }, { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "이제 `master` 브랜치에 `bugFix`를 합쳐(merge) 봅시다:" + "이제 `main` 브랜치에 `bugFix`를 합쳐(merge) 봅시다:" ], "afterMarkdowns": [ - "`bugFix`가 `master`의 부모쪽에 있었기 때문에, git이 별다른 일을 할 필요가 없었습니다; 간단히 `bugFix`를 `master`가 붙어 있는 커밋으로 이동시켰을 뿐입니다.", + "`bugFix`가 `main`의 부모쪽에 있었기 때문에, git이 별다른 일을 할 필요가 없었습니다; 간단히 `bugFix`를 `main`가 붙어 있는 커밋으로 이동시켰을 뿐입니다.", "", "짜잔! 이제 모든 커밋의 색이 같아졌고, 이는 두 브랜치가 모두 저장소의 모든 작업 내역을 포함하고 있다는 뜻입니다." ], - "command": "git checkout bugFix; git merge master", - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit; git merge bugFix" + "command": "git checkout bugFix; git merge main", + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit; git merge bugFix" } }, { @@ -642,9 +863,9 @@ exports.level = { "* `bugFix`라는 새 브랜치를 만듭니다", "* `git checkout bugFix`를 입력해 `bugFix` 브랜치로 이동(checkout)합니다.", "* 커밋 한 번 하세요", - "* `git checkout` 명령어를 이용해 `master`브랜치로 돌아갑니다", + "* `git checkout` 명령어를 이용해 `main`브랜치로 돌아갑니다", "* 커밋 또 하세요", - "* `git merge` 명령어로 `bugFix`브랜치를 `master`에 합쳐 넣습니다.", + "* `git merge` 명령어로 `bugFix`브랜치를 `main`에 합쳐 넣습니다.", "", "*아 그리고, \"objective\" 명령어로 이 안내창을 다시 볼 수 있다는 것을 기억해 두세요!*" ] @@ -674,32 +895,32 @@ exports.level = { "beforeMarkdowns": [ "Вот у нас две ветки, каждая содержит по одному уникальному коммиту. Это означает, что ни одна из веток не содержит полный набор \"работ\", выполненных в этом репозитории. Можно исправить эту ситуацию, выполнив слияние.", "", - "Мы сделаем `merge` ветки `bugFix` в ветку `master`" + "Мы сделаем `merge` ветки `bugFix` в ветку `main`." ], "afterMarkdowns": [ - "Что мы видим? Во-первых, ветка `master` теперь указывает на коммит, у которого два родителя. Если проследовать по стрелкам от этого коммита, вы пройдёте через каждый коммит в дереве прямиком к началу. Это означает, что теперь в ветке `master` содержатся все изменения репозитория.", + "Что мы видим? Во-первых, ветка `main` теперь указывает на коммит, у которого два родителя. Если проследовать по стрелкам от этого коммита, вы пройдёте через каждый коммит в дереве прямиком к началу. Это означает, что теперь в ветке `main` содержатся все изменения репозитория.", "", "Во-вторых, обрати внимание, как изменились цвета коммитов. Мы ввели цветовую дифференциацию, чтобы помочь пониманию. У каждой ветки — свой цвет. Каждый коммит становится того цвета, какого его ветка. Если в нём изменения сразу двух веток - он становится цветом, смешанным из цветов родительских веток.", "", - "И вот мы видим, что цвет ветки `master` подмешан к каждому коммиту, а ветки `bugFix` - нет. Это можно поправить." + "И вот мы видим, что цвет ветки `main` подмешан к каждому коммиту, а ветки `bugFix` - нет. Это можно поправить." ], "command": "git merge bugFix", - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit" + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" } }, { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Смерджим ветку `master` в ветку `bugFix`" + "Смерджим ветку `main` в ветку `bugFix`." ], "afterMarkdowns": [ - "Так как ветка `bugFix` была предшественницей `master`, Git не делал ничего, только сдвинул `bugFix` на тот же коммит, где находится `master`", + "Так как ветка `bugFix` была предшественницей `main`, Git не делал ничего, только сдвинул `bugFix` на тот же коммит, где находится `main`", "", "Теперь все коммиты одного цвета, что означает, что каждая ветка содержит все изменения репозитория! Поздравляем!" ], - "command": "git checkout bugFix; git merge master", - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit; git merge bugFix" + "command": "git checkout bugFix; git merge main", + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit; git merge bugFix" } }, { @@ -711,9 +932,9 @@ exports.level = { "* Создай новую ветку под названием `bugFix`", "* Переключись на новую ветку `bugFix` командой `git checkout bugFix`", "* Сделай один коммит", - "* Вернись на ветку `master` при помощи `git checkout`", + "* Вернись на ветку `main` при помощи `git checkout`", "* Сделай ещё один коммит", - "* Слей ветку `bugFix` с веткой `master` при помощи `git merge`", + "* Слей ветку `bugFix` с веткой `main` при помощи `git merge`", "", "* Если что-то пошло не так - можешь подглядеть в эту шпаргалку командой \"objective\"!*" ] @@ -743,32 +964,32 @@ exports.level = { "beforeMarkdowns": [ "Тут ми маємо дві гілки; кожна з них містить унікальний коміт. Це означає що жодна з них не містить повного набору \"робочої інфи\" в цьому репозиторії. Давайте зіллємо всю інфу докупи за допомогою merge.", "", - "Ми `змержимо` гілку `bugFix` в `master`" + "Ми `змержимо` гілку `bugFix` в `main`." ], "afterMarkdowns": [ - "Нічого собі! Ви це бачили? По-перше, `master` тепер вказує на коміт з двома батьками. Якщо ти піднімешся вверх з цього коміту по дереву, починаючи з `master`, на шляху ти зустрінеш кожен коміт аж до кореневого. Це означає що гілка `master` тепер містить всю інфу в цьому репозиторії.", + "Нічого собі! Ви це бачили? По-перше, `main` тепер вказує на коміт з двома батьками. Якщо ти піднімешся вверх з цього коміту по дереву, починаючи з `main`, на шляху ти зустрінеш кожен коміт аж до кореневого. Це означає що гілка `main` тепер містить всю інфу в цьому репозиторії.", "", "А ти помітив як змінилися кольори комітів? Для кращого розуміння процесу я додав певну кольорову диференціацію. Кожен бранч виділено окремим кольором. Колір кожного коміту це суміш кольорів всіх гілок що місять цей коміт.", "", - "Тож ми бачимо що колір гілки `master` містять всі коміти, але не колір `bugFix`. Давайте виправимо це..." + "Тож ми бачимо що колір гілки `main` містять всі коміти, але не колір `bugFix`. Давайте виправимо це..." ], "command": "git merge bugFix", - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit" + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" } }, { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Давай змержимо `master` в `bugFix`:" + "Давай змержимо `main` в `bugFix`:" ], "afterMarkdowns": [ - "Так як `bugFix` є нащадком `master`, git'у не потрібно нічого робити; він просто пересунув `bugFix` на тей самий коміт, на якому знаходиться `master`.", + "Так як `bugFix` є нащадком `main`, git'у не потрібно нічого робити; він просто пересунув `bugFix` на тей самий коміт, на якому знаходиться `main`.", "", "Тепер всі коміти одного кольору, що означає що кожен бранч включає в собі всю корисну інфу яка є в цьому репозиторії! Ура!" ], - "command": "git checkout bugFix; git merge master", - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit; git merge bugFix" + "command": "git checkout bugFix; git merge main", + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit; git merge bugFix" } }, { @@ -778,17 +999,293 @@ exports.level = { "Щоб пройти цей рівень виконай наступні кроки:", "", "* Зроби нову гілку (branch) з назвою `bugFix`", - "* Перейди на кілку `bugFix` за допомогою `git checkout bugFix`", + "* Перейди на гілку `bugFix` за допомогою `git checkout bugFix`", "* Зроби один коміт", - "* Повернись до `master` за допомогою `git checkout`", + "* Повернись до `main` за допомогою `git checkout`", "* Зроби ще один коміт", - "* Змерджи (злий) гілку `bugFix` в `master` за допомогою `git merge`", + "* Змерджи (злий) гілку `bugFix` в `main` за допомогою `git merge`", "", "*Не забувай, ти можеш завжди повернутися до цього діалогу за допомогою \"objective\"!*" ] } } ] + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Nhánh và gộp nhánh", + "", + "Tuyệt! Ta đã biết làm sao để commit và tạo nhánh. Giờ ta cần học cách để tập hợp thành quả của 2 nhánh khác biệt lại với nhau. Đây sẽ là cách để ta phân tách để phát triển chức năng, rồi sau đó hợp nhất nó trở lại.", + "", + "Cách đầu tiên để hợp nhất thành quả cần xem xét đến là lệnh `git merge`. Merge trong Git là tạo ra một commit đặc biệt mà có 2 người cha độc nhất. Một commit mà có 2 cha căn bản nghĩa là \"Tôi muốn có thành quả của ông này và ông kia nữa, *và* tất cả ông cha của họ.\"", + "", + "Trực quan thì dễ hiểu hơn, sang trang tiếp theo nào" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Ở đây ta có 2 nhánh; mỗi nhánh có 1 commit độc nhất. Có nghĩa là chẳng nhánh nào có đủ \"thành quả\" trong kho chứa của ta cả. Sửa nó bằng merge nào.", + "", + "Ta sẽ `merge` nhánh `bugFix` vào `main`." + ], + "afterMarkdowns": [ + "Wao! Thấy chứ? Trước tiên, `main` giờ đã trỏ đến commit có 2 cha. Nếu bạn lần theo mũi tên lên trên từ `main`, bạn sẽ gặp tất cả các commit lên đến commit gốc. Có nghĩa là `main` giờ đã chứa tất cả thành quả trong kho.", + "", + "Đồng thời, bạn thấy màu commit thay đổi chứ? Để bạn dễ học hơn, tôi đã phối hợp một số bảng màu. Mỗi nhánh có một màu duy nhất. Mỗi commit mang màu pha trộn của tất cả nhánh chứa nó.", + "", + "Vì vậy, ở đây chúng ta thấy rằng màu nhánh `main` được pha trộn vào tất cả các commit, nhưng màu` bugFix` thì không. Hãy sửa nó nào ..." + ], + "command": "git merge bugFix", + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Hãy gộp nhánh `main` vào `bugFix` nào:" + ], + "afterMarkdowns": [ + "Vì `bugFix` là bậc cha ông của `main`, git chẳng phải làm gì cả; nó đơn giản chỉ chuyển `bugFix` vào commit mà `main` đang trỏ tới.", + "", + "Giờ thì tất cả commit đã có cùng màu, nghĩa là mỗi nhánh đã chứa tất cả thành quả trong kho! Ồ hố!" + ], + "command": "git checkout bugFix; git merge main", + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit; git merge bugFix" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Để hoàn thành cấp độ này, hãy làm theo các bước bên dưới:", + "", + "* Tạo một nhánh mới tên là `bugFix`", + "* Chuyển sang nhánh `bugFix` với `git checkout bugFix`", + "* Commit một lần", + "* Trở về `main` với `git checkout`", + "* Commit một lần nữa", + "* Gộp nhánh `bugFix` vào `main` với `git merge`", + "", + "*Nhớ rằng, bạn luôn luôn có thể bật lại hội thoại này với lệnh \"objective\"!*" + ] + } + } + ] + }, + "sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Branchi in Merganje", + "", + "Odlično! Sedaj znamo commitati in branchati. Naslednja stvar je, da se naučimo združiti delo iz dveh različnih branchev. To nam bo omogočilo, da naredimo branch, razvijemo novo funkcionalnost in jo združimo nazaj.", + "", + "Prva metoda za združevanje dela, ki jo bomo preučili je `git merge`. Merganje v Gitu naredi poseben commit, ki ima dva edinstvena starša. Commit z dvema staršema v bistvu pomeni \"Hočem vključiti vso delo iz tega starša tukaj in iz tega tu *ter* vse delo iz njunih staršev\".", + "", + "Vizualizacija je enostavnejša, poglejmo v naslednjem oknu." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Tu imamo dva brancha; vsak ima en commit, ki je unikaten. To pomeni, da noben branch v repozitorju nima vsega \"dela\". Pa popravimo to z mergeom.", + "", + "Sedaj bomo `mergeali` branch `bugFix` v `main`." + ], + "afterMarkdowns": [ + "Woah! Si videl to? `main` sedaj kaže na commit, ki ima dva starša. Če slediš puščicam po drevesu commitov iz `main`, boš našel vsak commit po poti do roota. To pomeni, da `main` sedaj vsebuje vso delo iz repozitorija.", + "", + "Opaziš tudi, kako so se barve commitov spremenile? V pomoč pri učenju, sem vključil še nekaj barvne pomoči. Vsak branch ima svojo barvo. Vsak commit spremeni barvo v kombinirano barvo vseh branchev, ki imajo ta commit.", + "", + "Torej tukaj vidimo, da je `main` branch barva zmešana v vseh commitih, `bugFix` barva pa ne. Popravimo to ..." + ], + "command": "git merge bugFix", + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Zmergajmo sedaj `main` v `bugFix`:" + ], + "afterMarkdowns": [ + "Ker je `bugFix` bil prednik `main`, git ni rabil storiti ničesar; preprosto je premaknil `bugFix` v isti commit, kamer kaže `main`.", + "", + "Sedaj so vsi commiti iste barve, kar pomeni, da vsak branch vsebuje vse delo v repozitoriju!! Woohoo!" + ], + "command": "git checkout bugFix; git merge main", + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit; git merge bugFix" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Da zaključiš to stopnjo, naredi naslednje korake:", + "", + "* Naredi novi branch `bugFix`", + "* Checkoutaj `bugFix` branch z `git checkout bugFix`", + "* Enkrat commitaj", + "* Pojdi nazaj na `main` z `git checkout`", + "* Še enkrat commitaj", + "* Mergeaj branch `bugFix` v `main` z `git merge`", + "", + "*Pomni, vedno lahko spet pogledaš ta dialog z \"objective\"!*" + ] + } + } + ] + }, + "pl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Łączenie (scalanie) Branch-y", + "", + "Świetnie! Już wiemy, jak stworzyć commit-y oraz jak tworzyć branch-e. Teraz musimy się nauczyć jak połączyć pracę dwóch różnych branch-y. Stwórzmy nowy branch, wprowadzamy nową funkcjonalność, a następnie je połączymy.", + "", + "Pierwszą metodą łączenia pracy, którą zamierzamy użyć, jest `git merge`. Połączenie te tworzy w GIT specjalny commit, który ma dwóch różnych rodziców. Commit z dwojgiem rodziców zasadniczo oznacza: \"Chcę uwzględnić całą pracę tych dwóch rodziców oraz zbiory wszystkich swoich przodków\".", + "", + "Łatwiej będzie to wizualizować, zobaczymy to w następnym widoku." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Mamy tutaj dwa branch-e (gałęzie); każdy ma po jednym commit-cie, które są unikalne. Oznacza to, że żadna z branch-y nie zawiera \"całej pracy\", które jest w naszym repozytorium. Naprawmy to za pomocą funkcji marge.", + "", + "Użyjmy `merge` aby połączyć branch `bugFix` z `main`." + ], + "afterMarkdowns": [ + "Wow! Widzialiście to? Przede wszystkim \"main\" wskazuje teraz na commit, który ma dwoje rodziców. Jeśli podążasz za strzałkami w górę drzewa zatwierdzenia od `main`, trafisz na każdy commit po drodze do korzenia. Oznacza to, że `main` zawiera teraz całą pracę w repozytorium.", + "", + "Czy widziałeś również, jak zmieniły się kolory zatwierdzeń? Aby Ci pomóc w nauce, dołączyłem kilka konwencji kolorów. Każdy branch ma swój własny kolor. Każdy commit staje się kolorem wynikającym z mieszania kolorów wszystkich branch-y, które commit-ujesz", + "", + "Więc tutaj widzimy, że kolor branch-a `main` uczestniczy w miksowaniu wszystkich commit-ów, ale kolor branch-u `bugFix` już nie. Naprawmy to..." + ], + "command": "git merge bugFix", + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Połączmy brach `main` z branch `bugFix`:" + ], + "afterMarkdowns": [ + "Ponieważ `bugFix` był przodkiem branch-a `main`, GIT nie musiał wykonywać żadnej pracy; po prostu przeniosł branch `bugFix` do tego samego commit-a, do którego był dołączony branch `main`.", + "", + "Teraz wszystkie commit-y mają ten sam kolor, co oznacza, że każdy branch zawiera całą pracę znajdującą się w repozytorium! Super!" + ], + "command": "git checkout bugFix; git merge main", + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit; git merge bugFix" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Aby ukończyć ten poziom, wykonaj następujące czynności:", + "", + "* Stwórz nowy branch o nazwie `bugFix`", + "* Przełącz się na branch `bugFix`, używając polecenia `git checkout bugFix`", + "* Zrób commit", + "* Wróć do branch-u `main` za pomocą polecenia `git checkout`", + "* Zrób ponownie commit", + "* Złącz branch `bugFix` z branch-em `main` używając polecenia `git merge`", + "", + "*Pamiętaj: zawsze możesz zobaczyć tą wiadomość ponownie, wpisując \"objective\"!*" + ] + } + } + ] + }, + "ta_IN": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## கிளைகள் மற்றும் இணைத்தல்", + "", + "Great! We now know how to commit and branch. Now we need to learn some kind of way of combining the work from two different branches together. This will allow us to branch off, develop a new feature, and then combine it back in.", + "", + "The first method to combine work that we will examine is `git merge`. Merging in Git creates a special commit that has two unique parents. A commit with two parents essentially means \"I want to include all the work from this parent over here and this one over here, *and* the set of all their parents.\"", + "", + "It's easier with visuals, let's check it out in the next view." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Here we have two branches; each has one commit that's unique. This means that neither branch includes the entire set of \"work\" in the repository that we have done. Let's fix that with merge.", + "", + "We will `merge` the branch `bugFix` into `main`." + ], + "afterMarkdowns": [ + "Woah! See that? First of all, `main` now points to a commit that has two parents. If you follow the arrows up the commit tree from `main`, you will hit every commit along the way to the root. This means that `main` contains all the work in the repository now.", + "", + "Also, see how the colors of the commits changed? To help with learning, I have included some color coordination. Each branch has a unique color. Each commit turns a color that is the blended combination of all the branches that contain that commit.", + "", + "So here we see that the `main` branch color is blended into all the commits, but the `bugFix` color is not. Let's fix that..." + ], + "command": "git merge bugFix", + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Let's merge `main` into `bugFix`:" + ], + "afterMarkdowns": [ + "Since `bugFix` was an ancestor of `main`, git didn't have to do any work; it simply just moved `bugFix` to the same commit `main` was attached to.", + "", + "Now all the commits are the same color, which means each branch contains all the work in the repository! Woohoo!" + ], + "command": "git checkout bugFix; git merge main", + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit; git merge bugFix" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "To complete this level, do the following steps:", + "", + "* Make a new branch called `bugFix`", + "* Checkout the `bugFix` branch with `git checkout bugFix`", + "* Commit once", + "* Go back to `main` with `git checkout`", + "* Commit another time", + "* Merge the branch `bugFix` into `main` with `git merge`", + "", + "*Remember, you can always re-display this dialog with \"objective\"!*" + ] + } + } + ] } } }; diff --git a/src/levels/intro/rebasing.js b/src/levels/intro/rebasing.js index d3358634..befd7aef 100644 --- a/src/levels/intro/rebasing.js +++ b/src/levels/intro/rebasing.js @@ -1,18 +1,24 @@ exports.level = { "goalTreeString": "%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C3%22%2C%22id%22%3A%22master%22%7D%2C%22bugFix%22%3A%7B%22target%22%3A%22C2%27%22%2C%22id%22%3A%22bugFix%22%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C2%27%22%3A%7B%22parents%22%3A%5B%22C3%22%5D%2C%22id%22%3A%22C2%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22bugFix%22%2C%22id%22%3A%22HEAD%22%7D%7D", - "solutionCommand": "git checkout -b bugFix;git commit;git checkout master;git commit;git checkout bugFix;git rebase master", + "solutionCommand": "git checkout -b bugFix;git commit;git checkout main;git commit;git checkout bugFix;git rebase main", "name": { "en_US": "Rebase Introduction", "de_DE": "Einführung in Rebase", "ja" : "Rebaseの解説", "es_AR": "Introducción a rebase", + "es_MX": "Introducción a rebase", + "es_ES": "Introducción a rebase", "pt_BR": "Introdução ao rebase", + "gl" : "Introducción a rebase", "fr_FR": "Introduction à rebase", "ko": "리베이스(rebase)의 기본", "zh_CN": "Git Rebase", "zh_TW": "介紹 rebase", "ru_RU": "Введение в rebase", - "uk": "Знайомство з rebase" + "uk": "Знайомство з rebase", + "vi": "Giới thiệu về rebase", + 'sl_SI': 'Uvod v Rebase', + "pl" : "Wprowadzenie do Rebase" }, "hint": { "en_US": "Make sure you commit from bugFix first", @@ -20,12 +26,18 @@ exports.level = { "ja" : "初めにbugFixを指した状態でコミットする", "fr_FR": "Assurez-vous de bien faire votre commit sur bugFix en premier", "es_AR": "Asegurate de commitear desde bugFix primero", + "es_MX": "Asegúrate de hacer commit desde bugFix primero", + "es_ES": "Asegúrate de hacer commit desde bugFix primero", "pt_BR": "O bugFix precisa ser commitado primeiro", + "gl" : "Asegurate de facer o commit dende bugFix primeiro", "ko": "bugFix 브랜치에서 먼저 커밋하세요", "zh_CN": "先在 bugFix 分支上进行提交", "zh_TW": "你要先在 bugFix branch 進行 commit", "ru_RU": "Убедись, что сделал коммит в ветке bugFix", - "uk": "Впевнись, що зробив коміт в гілці bugFix" + "uk": "Впевнись, що зробив коміт в гілці bugFix", + "vi": "Hãy chắc chắn rằng bạn commit từ bugFix trước", + 'sl_SI': 'Prepričaj se, da si najprej commital bugFix.', + "pl" : "Upewnij się, że masz commit z bugFix" }, "disabledMap": { "git revert": true @@ -53,18 +65,18 @@ exports.level = { "beforeMarkdowns": [ "Here we have two branches yet again; note that the bugFix branch is currently selected (note the asterisk)", "", - "We would like to move our work from bugFix directly onto the work from master. That way it would look like these two features were developed sequentially, when in reality they were developed in parallel.", + "We would like to move our work from bugFix directly onto the work from main. That way it would look like these two features were developed sequentially, when in reality they were developed in parallel.", "", - "Let's do that with the `git rebase` command" + "Let's do that with the `git rebase` command." ], "afterMarkdowns": [ - "Awesome! Now the work from our bugFix branch is right on top of master and we have a nice linear sequence of commits.", + "Awesome! Now the work from our bugFix branch is right on top of main and we have a nice linear sequence of commits.", "", - "Note that the commit C3 still exists somewhere (it has a faded appearance in the tree), and C3' is the \"copy\" that we rebased onto master.", + "Note that the commit C3 still exists somewhere (it has a faded appearance in the tree), and C3' is the \"copy\" that we rebased onto main.", "", - "The only problem is that master hasn't been updated either, let's do that now..." + "The only problem is that main hasn't been updated either, let's do that now..." ], - "command": "git rebase master", + "command": "git rebase main", "beforeCommand": "git commit; git checkout -b bugFix C1; git commit" } }, @@ -72,13 +84,13 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Now we are checked out on the `master` branch. Let's go ahead and rebase onto `bugFix`..." + "Now we are checked out on the `main` branch. Let's go ahead and rebase onto `bugFix`..." ], "afterMarkdowns": [ - "There! Since `master` was an ancestor of `bugFix`, git simply moved the `master` branch reference forward in history." + "There! Since `main` was an ancestor of `bugFix`, git simply moved the `main` branch reference forward in history." ], "command": "git rebase bugFix", - "beforeCommand": "git commit; git checkout -b bugFix C1; git commit; git rebase master; git checkout master" + "beforeCommand": "git commit; git checkout -b bugFix C1; git commit; git rebase main; git checkout main" } }, { @@ -89,8 +101,8 @@ exports.level = { "", "* Checkout a new branch named `bugFix`", "* Commit once", - "* Go back to master and commit again", - "* Check out bugFix again and rebase onto master", + "* Go back to main and commit again", + "* Check out bugFix again and rebase onto main", "", "Good luck!" ] @@ -108,7 +120,7 @@ exports.level = { "", "Der zweite Weg um Inhalte aus verschiedenen Branches zu kombinieren ist `git rebase`. Rebasen nimmt im Prinzip eine Menge von Commits, \"kopiert\" sie und packt sie auf etwas anderes drauf.", "", - "Auch wenn das erst mal komisch klingt liegt der Vorteil von Rebase darin, dass man es benutzen kann um hübsch lineare Abfolgen von Commits zu erhalten. Das Commit-Protokoll des Repositorys wird durch Rebase eine ganze Ecke einfacher aussehen, weil Merge Commits vermieden werden.", + "Auch wenn das erst mal komisch klingt, liegt der Vorteil von Rebase darin, dass man es benutzen kann um hübsch lineare Abfolgen von Commits zu erhalten. Das Commit-Protokoll des Repositorys wird durch Rebase eine ganze Ecke einfacher aussehen, weil Merge Commits vermieden werden.", "", "Schauen wir's uns mal in Aktion an ..." ] @@ -120,18 +132,18 @@ exports.level = { "beforeMarkdowns": [ "Hier haben wir wieder zwei Branches; wie du siehst ist `bugFix` aktuell ausgewählt (sieht man am `*`).", "", - "Wir würden jetzt gerne unsere Arbeit aus `bugFix` direkt auf den `master` packen. Das Ergebnis wäre, dass alle aktuellen Änderungen in `master` auch im Branch `bugFix` sind.", + "Wir würden jetzt gerne unsere Arbeit aus `bugFix` direkt auf den `main` packen. Das Ergebnis wäre, dass alle aktuellen Änderungen in `main` auch im Branch `bugFix` sind.", "", "Das machen wir mit dem Befehl `git rebase`:" ], "afterMarkdowns": [ - "Hammer! Was wir in `bugFix` gemacht haben ist jetzt oben auf `master` draufgepackt und wir haben eine schön lineare Abfolge von Commits bekommen.", + "Hammer! Was wir in `bugFix` gemacht haben ist jetzt oben auf `main` draufgepackt und wir haben eine schön lineare Abfolge von Commits bekommen.", "", - "Commit `C3` existiert immer noch irgendwo (deswegen ist er blaß dargestellt) und `C3'` ist die \"Kopie\" die wir auf den `master` gepackt haben.", + "Commit `C3` existiert immer noch irgendwo (deswegen ist er blass dargestellt) und `C3'` ist die \"Kopie\" die wir auf den `main` gepackt haben.", "", - "Aber `master` ist jetzt nicht aktualisiert worden, lass uns das gerade noch nachholen ..." + "Aber `main` ist jetzt nicht aktualisiert worden, lass uns das gerade noch nachholen ..." ], - "command": "git rebase master", + "command": "git rebase main", "beforeCommand": "git commit; git checkout -b bugFix C1; git commit" } }, @@ -139,13 +151,13 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Jetzt sind wir im `master`. Lass uns den mal auf `bugFix` rebasen ..." + "Jetzt sind wir im `main`. Lass uns den mal auf `bugFix` rebasen ..." ], "afterMarkdowns": [ - "So! Da `master` ein Vorgänger von `bugFix` war konnte Git hier einfach den Bezeichner `master` auf denselben Commit schieben, auf den auch `bugFix` zeigt." + "So! Da `main` ein Vorgänger von `bugFix` war konnte Git hier einfach den Bezeichner `main` auf denselben Commit schieben, auf den auch `bugFix` zeigt." ], "command": "git rebase bugFix", - "beforeCommand": "git commit; git checkout -b bugFix C1; git commit; git rebase master; git checkout master" + "beforeCommand": "git commit; git checkout -b bugFix C1; git commit; git rebase main; git checkout main" } }, { @@ -156,8 +168,8 @@ exports.level = { "", "* Einen neuen Branch namens `bugFix` auschecken", "* Einen Commit machen", - "* Zurück zum `master` wechseln und noch einmal committen", - "* `bugFix` auschecken und auf den `master` rebasen", + "* Zurück zum `main` wechseln und noch einmal committen", + "* `bugFix` auschecken und auf den `main` rebasen", "", "Viel Erfolg!" ] @@ -198,7 +210,7 @@ exports.level = { "", "一つ問題が残ってて、masterブランチがまだ最新化されていませんね。ちょっと直してみましょう。。" ], - "command": "git rebase master", + "command": "git rebase main", "beforeCommand": "git commit; git checkout -b bugFix C1; git commit" } }, @@ -209,10 +221,10 @@ exports.level = { "masterブランチにチェックアウトしてあります。この状態からmasterブランチを`bugFix`へとリベースしてみましょう。" ], "afterMarkdowns": [ - "できた!`master`は`bugFix`の直前のコミットだったので、gitは単純に`master`ブランチのポインタを前に進めただけでした。" + "できた!`main`は`bugFix`の直前のコミットだったので、gitは単純に`main`ブランチのポインタを前に進めただけでした。" ], "command": "git rebase bugFix", - "beforeCommand": "git commit; git checkout -b bugFix C1; git commit; git rebase master; git checkout master" + "beforeCommand": "git commit; git checkout -b bugFix C1; git commit; git rebase main; git checkout main" } }, { @@ -240,7 +252,7 @@ exports.level = { "markdowns": [ "## Git Rebase", "", - "El segundo modo de combinar el trabajo de distintas ramas es el *rebase*. Rebasear escencialmente agarra un conjunto de commits, los \"copia\", y los aplica sobre algún otro lado.", + "El segundo modo de combinar el trabajo de distintas ramas es el *rebase*. Rebasear esencialmente agarra un conjunto de commits, los \"copia\", y los aplica sobre algún otro lado.", "", "Aunque esto pueda sonar confuso, la ventaja de rebasear es que puede usarse para conseguir una secuencia de commits lineal, más bonita. El historial / log de commits del repositorio va a estar mucho más claro si sólo usás rebase.", "", @@ -254,18 +266,18 @@ exports.level = { "beforeMarkdowns": [ "Acá tenemos dos ramas otra vez. Notar que la rama bugFix está actualmente seleccionada (tiene un asterisco)", "", - "Nos gustaría mover nuestro trabajo de bugFix directamente sobre el trabajo de master. De ese modo, parecería que esas dos tareas se desarrollaron secuencialmente, cuando en realidad se hicieron en paralelo.", + "Nos gustaría mover nuestro trabajo de bugFix directamente sobre el trabajo de main. De ese modo, parecería que esas dos tareas se desarrollaron secuencialmente, cuando en realidad se hicieron en paralelo.", "", - "Hagámoslo usando el comando `git rebase`" + "Hagámoslo usando el comando `git rebase`." ], "afterMarkdowns": [ - "¡Genial! Ahora el trabajo de nuestra rama bugFix está justo encima del de master, y tenemos una secuencia lineal de commits.", + "¡Genial! Ahora el trabajo de nuestra rama bugFix está justo encima del de main, y tenemos una secuencia lineal de commits.", "", - "Notá que el commit C3 sigue existiendo en algún lado (aparece medio desvanecido en el árbol), y C3' es la \"copia\" que rebaseamos sobre master.", + "Notá que el commit C3 sigue existiendo en algún lado (aparece medio desvanecido en el árbol), y C3' es la \"copia\" que rebaseamos sobre main.", "", - "El único problema es que master todavía no se actualizó, resolvámoslo ahora..." + "El único problema es que main todavía no se actualizó, resolvámoslo ahora..." ], - "command": "git rebase master", + "command": "git rebase main", "beforeCommand": "git commit; git checkout -b bugFix C1; git commit" } }, @@ -273,13 +285,13 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Ahora estamos parados sobre la rama `master`. Avancemos y rebaseémosla sobre `bugFix`..." + "Ahora estamos parados sobre la rama `main`. Avancemos y rebaseémosla sobre `bugFix`..." ], "afterMarkdowns": [ - "¡Ahí está! Como `master` era un ancestro de `bugFix`, git simplemente movió la referencia de `master` hacia adelante en la historia." + "¡Ahí está! Como `main` era un ancestro de `bugFix`, git simplemente movió la referencia de `main` hacia adelante en la historia." ], "command": "git rebase bugFix", - "beforeCommand": "git commit; git checkout -b bugFix C1; git commit; git rebase master; git checkout master" + "beforeCommand": "git commit; git checkout -b bugFix C1; git commit; git rebase main; git checkout main" } }, { @@ -290,8 +302,8 @@ exports.level = { "", "* Checkouteá una nueva rama llamada `bugFix`", "* Commiteá una vez", - "* Volvé a master y commiteå de nuevo", - "* Checkoutá bugFix otra vez y rebaseala sobre master", + "* Volvé a main y commiteå de nuevo", + "* Checkoutá bugFix otra vez y rebaseala sobre main", "", "¡Éxitos!" ] @@ -299,6 +311,140 @@ exports.level = { } ] }, + "es_MX": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Rebase", + "", + "El segundo modo de combinar el trabajo de distintas ramas es el *rebase*. Rebasear esencialmente agarra un conjunto de commits, los \"copia\", y los aplica sobre algún otro lado.", + "", + "Aunque esto pueda sonar confuso, la ventaja de rebasear es que puede usarse para conseguir una secuencia de commits lineal, más bonita. El historial / log de commits del repositorio va a estar mucho más claro si sólo usas rebase.", + "", + "Veámoslo en acción..." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Acá tenemos dos ramas otra vez. Nota que la rama bugFix está actualmente seleccionada (tiene un asterisco)", + "", + "Nos gustaría mover nuestro trabajo de bugFix directamente sobre el trabajo de main. De ese modo, parecería que esas dos tareas se desarrollaron secuencialmente, cuando en realidad se hicieron en paralelo.", + "", + "Hagámoslo usando el comando `git rebase`." + ], + "afterMarkdowns": [ + "¡Genial! Ahora el trabajo de nuestra rama bugFix está justo encima del de main, y tenemos una secuencia lineal de commits.", + "", + "Notá que el commit C3 sigue existiendo en algún lado (aparece medio desvanecido en el árbol), y C3' es la \"copia\" que rebaseamos sobre main.", + "", + "El único problema es que main todavía no se actualizó, resolvámoslo ahora..." + ], + "command": "git rebase main", + "beforeCommand": "git commit; git checkout -b bugFix C1; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Ahora estamos parados sobre la rama `main`. Avancemos y rebaseémosla sobre `bugFix`..." + ], + "afterMarkdowns": [ + "¡Ahí está! Como `main` era un ancestro de `bugFix`, git simplemente movió la referencia de `main` hacia adelante en la historia." + ], + "command": "git rebase bugFix", + "beforeCommand": "git commit; git checkout -b bugFix C1; git commit; git rebase main; git checkout main" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para completar este nivel, haz lo siguiente:", + "", + "* Cámbiate a una nueva rama llamada `bugFix`", + "* Haz un commit de una vez", + "* Vuelve a main y haz commit de nuevo", + "* Cámbiate a la rama bugFix otra vez y rebaséala sobre main", + "", + "¡Éxitos!" + ] + } + } + ] + }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Rebase", + "", + "El segundo modo de combinar el trabajo de distintas ramas es el *rebase*. Hacer rebase escencialmente selecciona un conjunto de commits, los \"copia\", y los aplica en algún otro lado.", + "", + "Aunque esto pueda sonar confuso, la ventaja de hacer rebase es que puede usarse para conseguir una secuencia de commits lineal, más bonita. El historial / log de commits del repositorio va a estar mucho más claro si sólo usas rebase.", + "", + "Veámoslo en acción..." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Aquí tenemos dos ramas otra vez. Observa que la rama bugFix está actualmente seleccionada (tiene un asterisco)", + "", + "Nos gustaría mover nuestro trabajo de bugFix directamente sobre el trabajo de main. De ese modo, parecería que esas dos tareas se desarrollaron secuencialmente, cuando en realidad se hicieron en paralelo.", + "", + "Hagámoslo usando el comando `git rebase`." + ], + "afterMarkdowns": [ + "¡Genial! Ahora el trabajo de nuestra rama bugFix está justo encima del de main, y tenemos una secuencia lineal de commits.", + "", + "Nota que el commit C3 sigue existiendo en algún lado (aparece medio desvanecido en el árbol), y C3' es la \"copia\" que rebaseamos sobre main.", + "", + "El único problema es que main todavía no se actualizó, resolvámoslo ahora..." + ], + "command": "git rebase main", + "beforeCommand": "git commit; git checkout -b bugFix C1; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Ahora estamos parados sobre la rama `main`. Avancemos y hagamos rebase sobre `bugFix`..." + ], + "afterMarkdowns": [ + "¡Ahí está! Como `main` era un ancestro de `bugFix`, git simplemente movió la referencia de `main` hacia adelante en la historia." + ], + "command": "git rebase bugFix", + "beforeCommand": "git commit; git checkout -b bugFix C1; git commit; git rebase main; git checkout main" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para completar este nivel, haz lo siguiente:", + "", + "* Haz checkout de una nueva rama llamada `bugFix`", + "* Crea un commit", + "* Vuelve a la rama main y crea otro commit", + "* Haz checkout en bugFix otra vez y haz rebase sobre main", + "", + "¡Misión cumplida!" + ] + } + } + ] + }, "pt_BR": { "childViews": [ { @@ -321,18 +467,18 @@ exports.level = { "beforeMarkdowns": [ "Aqui temos dois ramos novamente; note que o ramo bugFix está atualmente ativo (veja o asterisco)", "", - "Queremos mover nosso trabalho do bugFix diretamente dentro do master. Desta forma, vai parecer que esses dois recursos foram desenvolvidos sequencialmente, quando na realidade foram feitos em paralelo.", + "Queremos mover nosso trabalho do bugFix diretamente dentro do main. Desta forma, vai parecer que esses dois recursos foram desenvolvidos sequencialmente, quando na realidade foram feitos em paralelo.", "", - "Vamos fazê-lo com o comando `git rebase`" + "Vamos fazê-lo com o comando `git rebase`." ], "afterMarkdowns": [ - "Incrível! Agora o trabalho do nosso ramo bugFix está logo após o do master, e temos uma linda sequência linear de commits.", + "Incrível! Agora o trabalho do nosso ramo bugFix está logo após o do main, e temos uma linda sequência linear de commits.", "", - "Perceba que o commit C3 ainda existe em algum lugar (ele está clareado na árvore), e que o C3' é a \"cópia\" que rebaseamos no master.", + "Perceba que o commit C3 ainda existe em algum lugar (ele está clareado na árvore), e que o C3' é a \"cópia\" que rebaseamos no main.", "", - "O único problema é que o master não foi atualizado também, vamos fazê-lo agora..." + "O único problema é que o main não foi atualizado também, vamos fazê-lo agora..." ], - "command": "git rebase master", + "command": "git rebase main", "beforeCommand": "git commit; git checkout -b bugFix C1; git commit" } }, @@ -340,13 +486,13 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Agora o ramo `master` está ativo. Vamos em frente, fazer rebase no `bugFix`..." + "Agora o ramo `main` está ativo. Vamos em frente, fazer rebase no `bugFix`..." ], "afterMarkdowns": [ - "Aí está! Como o `master` era um ancestral do `bugFix`, o git simplesmente moveu a referência do ramo `master` para frente na história." + "Aí está! Como o `main` era um ancestral do `bugFix`, o git simplesmente moveu a referência do ramo `main` para frente na história." ], "command": "git rebase bugFix", - "beforeCommand": "git commit; git checkout -b bugFix C1; git commit; git rebase master; git checkout master" + "beforeCommand": "git commit; git checkout -b bugFix C1; git commit; git rebase main; git checkout main" } }, { @@ -357,8 +503,75 @@ exports.level = { "", "* Faça checkout de um novo branch chamado `bugFix`", "* Faça um commit", - "* Volte ao master e faça um novo commit", - "* Faça checkout do bugFix novamente e faça rebase no master", + "* Volte ao main e faça um novo commit", + "* Faça checkout do bugFix novamente e faça rebase no main", + "", + "Boa sorte!" + ] + } + } + ] + }, + "gl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Rebase en Git", + "", + "A segunda forma de mesturar traballo entre ramas é o *rebase*. O rebase esencialmente pega un conxunto de commits, \"copia\" os commits, e os sitúa en outro lugar.", + "", + "Esto pode paracer confuso, pero a vantaxe do rebase é que se pode usar para construír unha secuencia máis bonita e linial de commits. O rexisto de commits do repositorio estará máis limpo se só se permite facer rebases.", + "", + "Ímolo ver en acción..." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Aquí temos dúas ramas novamente; decátate de que a rama `bugFix` está seleccionada (olla ó asterisco)", + "", + "Queremos mover o noso traballo do `bugFix` directamente dentro da rama `main`. Desta forma, vai parecer que eses dous recursos foron editados secuencialmente, cando a realidade é que se fixeron en paralelo.", + "", + "Imos lanzar o comando `git rebase`." + ], + "afterMarkdowns": [ + "¡Buah chorvo! Agora o traballo da nosa rama `bugFix` está seguida de main, e temos unha fermosa línea de commits.", + "", + "Percibe que o commit `C3` aínda existe nalgún lugar (el está borrado na árbore), e que `C3'` é a \"copia\" que rebasamos en main.", + "", + "O único problema é que a rama main non foi actualizada tamén, ímolo facer agora..." + ], + "command": "git rebase main", + "beforeCommand": "git commit; git checkout -b bugFix C1; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Agora a rama `main` está ativa. Continuamos facendo o rebase na `bugFix`..." + ], + "afterMarkdowns": [ + "¡Xa está! Como `main` era um ancestro de `bugFix`, git simplemente moveu a referencia da rama `main` máis adiante na historia." + ], + "command": "git rebase bugFix", + "beforeCommand": "git commit; git checkout -b bugFix C1; git commit; git rebase main; git checkout main" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para completar este nivel, fai o seguinte", + "", + "* Fai checkout de un novo branch chamado `bugFix`", + "* Fai un commit", + "* Regresa a main e fai un commit novamente", + "* Móvete á rama bugFix outra vez e fai rebase sobre main", "", "Boa sorte!" ] @@ -386,20 +599,20 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Ici nous avons encore une fois deux branches; notez que nous sommes sur la branche bugFix (cf. l'asterisque)", + "Ici nous avons encore une fois deux branches; notez que nous sommes sur la branche bugFix (cf. l'astérisque)", "", - "Nous voudrions transférer notre travail de la branche 'bugFix' directement sur le travail existant dans 'master'. Ainsi on aurait l'impression que ces deux travaux ont été développés séquentiellement alors qu'en réalité ils ont été réalisés en parallèle.", + "Nous voudrions transférer notre travail de la branche 'bugFix' directement sur le travail existant dans 'main'. Ainsi on aurait l'impression que ces deux travaux ont été développés séquentiellement alors qu'en réalité ils ont été réalisés en parallèle.", "", - "Faisons cela avec la commande `git rebase`" + "Faisons cela avec la commande `git rebase`." ], "afterMarkdowns": [ - "Super! Désormais, le travail de la branche 'bugFix' est juste en haut de la branche 'master' et nous avons une belle séquence linéaire de commits.", + "Super! Désormais, le travail de la branche 'bugFix' est juste en haut de la branche 'main' et nous avons une belle séquence linéaire de commits.", "", - "Notez que le commit C3 existe toujours quelque part (il est en grisé sur l'arbre), et C3' est la \"copie\" que nous avons créée sur master avec rebase.", + "Notez que le commit C3 existe toujours quelque part (il est en grisé sur l'arbre), et C3' est la \"copie\" que nous avons créée sur main avec rebase.", "", - "Le seul problème est que master n'a pas été mis à jour, faisons cela maintenant…" + "Le seul problème est que main n'a pas été mis à jour, faisons cela maintenant…" ], - "command": "git rebase master", + "command": "git rebase main", "beforeCommand": "git commit; git checkout -b bugFix C1; git commit" } }, @@ -407,11 +620,16 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Nous sommes désormais positionnés sur la branche `master`. Continuons en faisant le rebase sur `bugFix`…", - "Et voilà ! Puisque `master` était un ascendant de `bugFix`, git a simplement déplacé la référence de la branche `master` en avant dans le temps." + "Nous sommes désormais positionnés sur la branche `main`. Continuons en faisant le rebase sur `bugFix`…", + "Et voilà ! Puisque `main` était un ascendant de `bugFix`, git a simplement déplacé la référence de la branche `main` en avant dans le temps." + ], + "afterMarkdowns": [ + "Voilà vous avez vu comment cela fonctionne", + "", + "Continuons et essayons ce niveau !" ], "command": "git rebase bugFix", - "beforeCommand": "git commit; git checkout -b bugFix C1; git commit; git rebase master; git checkout master" + "beforeCommand": "git commit; git checkout -b bugFix C1; git commit; git rebase main; git checkout main" } }, { @@ -422,8 +640,8 @@ exports.level = { "", "* Positionnez-vous (checkout) sur une nouvelle branche nommée `bugFix`", "* Faites un commit", - "* Retournez sur master et faites un nouveau commit", - "* Positionnez-vous à nouveau sur bugFix et faites un rebase sur master", + "* Retournez sur main et faites un nouveau commit", + "* Positionnez-vous à nouveau sur bugFix et faites un rebase sur main", "", "Bonne chance !" ] @@ -453,17 +671,17 @@ exports.level = { "beforeMarkdowns": [ "还是准备了两个分支;注意当前所在的分支是 bugFix(星号标识的是当前分支)", "", - "我们想要把 bugFix 分支里的工作直接移到 master 分支上。移动以后会使得两个分支的功能看起来像是按顺序开发,但实际上它们是并行开发的。", + "我们想要把 bugFix 分支里的工作直接移到 main 分支上。移动以后会使得两个分支的功能看起来像是按顺序开发,但实际上它们是并行开发的。", "", "咱们这次用 `git rebase` 实现此目标" ], - "command": "git rebase master", + "command": "git rebase main", "afterMarkdowns": [ - "怎么样?!现在 bugFix 分支上的工作在 master 的最顶端,同时我们也得到了一个更线性的提交序列。", + "怎么样?!现在 bugFix 分支上的工作在 main 的最顶端,同时我们也得到了一个更线性的提交序列。", "", - "注意,提交记录 C3 依然存在(树上那个半透明的节点),而 C3' 是我们 Rebase 到 master 分支上的 C3 的副本。", + "注意,提交记录 C3 依然存在(树上那个半透明的节点),而 C3' 是我们 Rebase 到 main 分支上的 C3 的副本。", "", - "现在唯一的问题就是 master 还没有更新,下面咱们就来更新它吧……" + "现在唯一的问题就是 main 还没有更新,下面咱们就来更新它吧……" ], "beforeCommand": "git commit; git checkout -b bugFix C1; git commit" } @@ -472,13 +690,13 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "现在我们切换到了 `master` 上。把它 rebase 到 `bugFix` 分支上……" + "现在我们切换到了 `main` 上。把它 rebase 到 `bugFix` 分支上……" ], "command": "git rebase bugFix", "afterMarkdowns": [ - "好了!由于 `bugFix` 继承自 `master`,所以 Git 只是简单的把 `master` 分支的引用向前移动了一下而已。" + "好了!由于 `bugFix` 继承自 `main`,所以 Git 只是简单的把 `main` 分支的引用向前移动了一下而已。" ], - "beforeCommand": "git commit; git checkout -b bugFix C1; git commit; git rebase master; git checkout master" + "beforeCommand": "git commit; git checkout -b bugFix C1; git commit; git rebase main; git checkout main" } }, { @@ -489,8 +707,8 @@ exports.level = { "", "* 新建并切换到 `bugFix` 分支", "* 提交一次", - "* 切换回 master 分支再提交一次", - "* 再次切换到 bugFix 分支,rebase 到 master 上", + "* 切换回 main 分支再提交一次", + "* 再次切换到 bugFix 分支,rebase 到 main 上", "", "祝你好运!" ] @@ -520,17 +738,17 @@ exports.level = { "beforeMarkdowns": [ "這裡,還是有兩個 branch;注意目前我們所在的 branch 是 bugFix(看那顆星啦)", "", - "我們想要把在 bugfix 所做的修改直接移到 master branch上。使用 rebasing 的話,兩個 branch 看起來像是依序按順序進行修改,實際上它們的修改是平行進行的。", + "我們想要把在 bugfix 所做的修改直接移到 main branch上。使用 rebasing 的話,兩個 branch 看起來像是依序按順序進行修改,實際上它們的修改是平行進行的。", "", "用 `git rebase` 來實現吧" ], - "command": "git rebase master", + "command": "git rebase main", "afterMarkdowns": [ - "很厲害吧!現在 bugFix branch 上的工作在 master branch 的最前端,同時我們也得到了一個更加線性的 commit 順序。", + "很厲害吧!現在 bugFix branch 上的工作在 main branch 的最前端,同時我們也得到了一個更加線性的 commit 順序。", "", - "注意,本來的 commit C3 沒有消失(在圖上面呈現陰影),而我們\"複製\" C3,將它的副本 C3' 接在 master branch 的後面。", + "注意,本來的 commit C3 沒有消失(在圖上面呈現陰影),而我們\"複製\" C3,將它的副本 C3' 接在 main branch 的後面。", "", - "現在唯一的問題是 master branch 還沒有更新...我們接下來就更新它吧!" + "現在唯一的問題是 main branch 還沒有更新...我們接下來就更新它吧!" ], "beforeCommand": "git commit; git checkout -b bugFix C1; git commit" } @@ -539,13 +757,13 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "現在,切換到 `master` branch。接下來就把它 rebase 到 `bugFix` 上面吧..." + "現在,切換到 `main` branch。接下來就把它 rebase 到 `bugFix` 上面吧..." ], "command": "git rebase bugFix", "afterMarkdowns": [ - "完成!因為 `master` branch 是 `bugFix` 的 parent,所以 git 只是把 `master` branch 往前移動到 `bugFix` 上。" + "完成!因為 `main` branch 是 `bugFix` 的 parent,所以 git 只是把 `main` branch 往前移動到 `bugFix` 上。" ], - "beforeCommand": "git commit; git checkout -b bugFix C1; git commit; git rebase master; git checkout master" + "beforeCommand": "git commit; git checkout -b bugFix C1; git commit; git rebase main; git checkout main" } }, { @@ -556,8 +774,8 @@ exports.level = { "", "* 建立 `bugFix` branch", "* commit 一次", - "* 切換回 master branch 再 commit 一次", - "* 再次切換到 bugFix branch,接著 rebase bugFix 這個 branch 到 master branch 上", + "* 切換回 main branch 再 commit 一次", + "* 再次切換到 bugFix branch,接著 rebase bugFix 這個 branch 到 main branch 上", "", "祝你好運啦!" ] @@ -575,7 +793,7 @@ exports.level = { "", "브랜치끼리의 작업을 접목하는 두번째 방법은 *리베이스(rebase)*입니다. 리베이스는 기본적으로 커밋들을 모아서 복사한 뒤, 다른 곳에 떨궈 놓는 것입니다.", "", - "조금 어려게 느껴질 수 있지만, 리베이스를 하면 커밋들의 흐름을 보기 좋게 한 줄로 만들 수 있다는 장점이 있습니다. 리베이스를 쓰면 저장소의 커밋 로그와 이력이 한결 깨끗해집니다.", + "조금 어렵게 느껴질 수 있지만, 리베이스를 하면 커밋들의 흐름을 보기 좋게 한 줄로 만들 수 있다는 장점이 있습니다. 리베이스를 쓰면 저장소의 커밋 로그와 이력이 한결 깨끗해집니다.", "", "어떻게 동작하는지 살펴볼까요..." ] @@ -587,18 +805,18 @@ exports.level = { "beforeMarkdowns": [ "여기 또 브랜치 두 개가 있습니다; bugFix브랜치가 현재 선택됐다는 점 눈여겨 보세요 (별표 표시)", "", - "bugFix 브랜치에서의 작업을 master 브랜치 위로 직접 옮겨 놓으려고 합니다. 그렇게 하면, 실제로는 두 기능을 따로따로 개발했지만, 마치 순서대로 개발한 것처럼 보이게 됩니다.", + "bugFix 브랜치에서의 작업을 main 브랜치 위로 직접 옮겨 놓으려고 합니다. 그렇게 하면, 실제로는 두 기능을 따로따로 개발했지만, 마치 순서대로 개발한 것처럼 보이게 됩니다.", "", "`git rebase` 명령어로 함께 해보죠." ], "afterMarkdowns": [ - "오! 이제 bugFix 브랜치의 작업 내용이 master의 바로 위에 깔끔한 한 줄의 커밋으로 보이게 됐습니다.", + "오! 이제 `bugFix` 브랜치의 작업 내용이 `main`의 바로 위에 깔끔한 한 줄의 커밋으로 보이게 됐습니다.", "", - "C3 커밋은 어딘가에 아직 남아있고(그림에서 흐려짐), C3'는 master 위에 올려 놓은 복사본입니다.", + "C3 커밋은 어딘가에 아직 남아있고(그림에서 흐려짐), C3'는 `main` 위에 올려 놓은 복사본입니다.", "", - "master가 아직 그대로라는 문제가 남아있는데요, 바로 해결해보죠..." + "`main`이 아직 그대로라는 문제가 남아있는데요, 바로 해결해보죠..." ], - "command": "git rebase master", + "command": "git rebase main", "beforeCommand": "git commit; git checkout -b bugFix C1; git commit" } }, @@ -606,13 +824,13 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "우리는 지금 `master` 브랜치를 선택한 상태입니다. `bugFix` 브랜치쪽으로 리베이스 해보겠습니다..." + "우리는 지금 `main` 브랜치를 선택한 상태입니다. `bugFix` 브랜치쪽으로 리베이스 해보겠습니다..." ], "afterMarkdowns": [ - "보세요! `master`가 `bugFix`의 부모쪽에 있었기 때문에, 단순히 그 브랜치를 더 앞쪽의 커밋을 가리키게 이동하는 것이 전부입니다." + "보세요! `main`이 `bugFix`의 부모쪽에 있었기 때문에, 단순히 그 브랜치를 더 앞쪽의 커밋을 가리키게 이동하는 것이 전부입니다." ], "command": "git rebase bugFix", - "beforeCommand": "git commit; git checkout -b bugFix C1; git commit; git rebase master; git checkout master" + "beforeCommand": "git commit; git checkout -b bugFix C1; git commit; git rebase main; git checkout main" } }, { @@ -623,8 +841,8 @@ exports.level = { "", "* `bugFix`라는 새 브랜치를 만들어 선택하세요", "* 커밋 한 번 합니다", - "* master로 돌아가서 또 커밋합니다", - "* bugFix를 다시 선택하고 master에 리베이스 하세요", + "* `main` 브랜치로 돌아가서 또 커밋합니다", + "* `bugFix`를 다시 선택하고 `main`에 리베이스 하세요", "", "화이팅!" ] @@ -654,18 +872,18 @@ exports.level = { "beforeMarkdowns": [ "У нас здесь снова две ветки. Обрати внимание, что выбрана ветка `bugFix` (отмечена звёздочкой)", "", - "Хочется сдвинуть наши изменения из `bugFix` прямо на вершину ветки `master`. Благодаря этому всё будет выглядеть, как будто эти изменения делались последовательно, хотя на самом деле - параллельно.", + "Хочется сдвинуть наши изменения из `bugFix` прямо на вершину ветки `main`. Благодаря этому всё будет выглядеть, как будто эти изменения делались последовательно, хотя на самом деле - параллельно.", "", - "Применим `git rebase`" + "Применим `git rebase`." ], "afterMarkdowns": [ - "Супер! Теперь изменения из `bugFix` находятся в конце ветки `master` и являют собой линейную последовательность коммитов.", + "Супер! Теперь изменения из `bugFix` находятся в конце ветки `main` и являют собой линейную последовательность коммитов.", "", - "Обрати внимание, что коммит С3 до сих пор существует где-то, а С3' - это его \"копия\" в ветке `master`", + "Обрати внимание, что коммит С3 до сих пор существует где-то, а С3' - это его \"копия\" в ветке `main`", "", - "Единственная проблема - ветка `master` не обновлена до последних изменений. Это легко исправить." + "Единственная проблема - ветка `main` не обновлена до последних изменений. Это легко исправить." ], - "command": "git rebase master", + "command": "git rebase main", "beforeCommand": "git commit; git checkout -b bugFix C1; git commit" } }, @@ -673,13 +891,13 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Вот мы выбрали ветку `master`. Вперёд - сделаем rebase на `bugFix`" + "Вот мы выбрали ветку `main`. Вперёд - сделаем rebase на `bugFix`." ], "afterMarkdowns": [ - "Вуаля! Так как `master` был предком `bugFix`, git просто сдвинул ссылку на `master` вперёд." + "Вуаля! Так как `main` был предком `bugFix`, git просто сдвинул ссылку на `main` вперёд." ], "command": "git rebase bugFix", - "beforeCommand": "git commit; git checkout -b bugFix C1; git commit; git rebase master; git checkout master" + "beforeCommand": "git commit; git checkout -b bugFix C1; git commit; git rebase main; git checkout main" } }, { @@ -690,8 +908,8 @@ exports.level = { "", "* Переключись на ветку `bugFix`", "* Сделай коммит", - "* Вернись на `master` и сделай коммит ещё раз", - "* Переключись на `bugFix` и сделай rebase на `master`", + "* Вернись на `main` и сделай коммит ещё раз", + "* Переключись на `bugFix` и сделай rebase на `main`", "", "Удачи!" ] @@ -721,18 +939,18 @@ exports.level = { "beforeMarkdowns": [ "Ми знову маємо дві гілки; зауваж, що наразі вибрана гілка bugFix (вважай зірочку)", "", - "Ми хочемо перемістити наші зміни з гілки bugFix прямо до змін з гілки master. Тоді це буде виглядати наче ці зміни були додані одна за одною, хоча насправді вони були додані одночасно.", + "Ми хочемо перемістити наші зміни з гілки bugFix прямо до змін з гілки main. Тоді це буде виглядати наче ці зміни були додані одна за одною, хоча насправді вони були додані одночасно.", "", - "Давайте зробимо це за допомогою команди `git rebase`" + "Давайте зробимо це за допомогою команди `git rebase`." ], "afterMarkdowns": [ - "Добре! Тепер зміни з гілки bugFix знаходяться прямо попереду змін з master й ми отримали зручну лінійну послідовність комітів.", + "Добре! Тепер зміни з гілки bugFix знаходяться прямо попереду змін з main й ми отримали зручну лінійну послідовність комітів.", "", - "Вважай що коміт C3 досі десь існує (в дереві він тьмяніший за решту), й C3' це \"копія\" яку ми заребейсили в master.", + "Вважай що коміт C3 досі десь існує (в дереві він тьмяніший за решту), й C3' це \"копія\" яку ми заребейсили в main.", "", - "Є лише одна проблема: гілка master також не була оновлена, давайте зробимо це наступним кроком..." + "Є лише одна проблема: гілка main також не була оновлена, давайте зробимо це наступним кроком..." ], - "command": "git rebase master", + "command": "git rebase main", "beforeCommand": "git commit; git checkout -b bugFix C1; git commit" } }, @@ -740,13 +958,13 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Тепер ми перейшли (checkout) до гілки `master`. Далі робимо rebase на `bugFix`..." + "Тепер ми перейшли (checkout) до гілки `main`. Далі робимо rebase на `bugFix`..." ], "afterMarkdowns": [ - "Вуаля! Так як `master` це предок `bugFix`, git просто просунув посилання гілки `master` вперед в історії." + "Вуаля! Так як `main` це предок `bugFix`, git просто просунув посилання гілки `main` вперед в історії." ], "command": "git rebase bugFix", - "beforeCommand": "git commit; git checkout -b bugFix C1; git commit; git rebase master; git checkout master" + "beforeCommand": "git commit; git checkout -b bugFix C1; git commit; git rebase main; git checkout main" } }, { @@ -757,14 +975,214 @@ exports.level = { "", "* Зачекауть (checkout) новий бранч з назвою `bugFix`", "* Зроби один коміт", - "* Повернись на master й зроби ще один коміт", - "* Зачекауть bugFix знову й заребейсь його на master", + "* Повернись на main й зроби ще один коміт", + "* Зачекауть bugFix знову й заребейсь його на main", "", "Нехай щастить!" ] } } ] + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Rebase", + "", + "Cách thứ 2 để kết hợp thành của của 2 nhánh là *rebase.* Rebase về căn bản là chọn một loạt các commit, \"sao chép\" chúng, và ném chúng sang chỗ khác.", + "", + "Nghe có vẻ phức tạp, lợi thế của rebase là có thể tạo ra cây lịch sử thẳng tuột. Ljch sử commit nhìn sẽ gọn gàng hơn nhiều.", + "", + "Xem nó hoạt động thế nào nào..." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Giờ ta lại có 2 nhánh; để ý rằng nhánh bugFix đang được chọn (thấy dấu hoa thị chứ?)", + "", + "Ta muốn chuyển bugFix trực tiếp sang main. Theo cách đó thì các chức năng nhìn có vẻ được phát triển tuần tự, trong khi thực tế chúng được phát triển song song.", + "", + "Dùng lệnh `git rebase` để thử nào" + ], + "afterMarkdowns": [ + "Tuyệt vời! Giờ thành quả của nhánh bugFix nằm ngay trên main và ta có các commit nằm thẳng tuột.", + "", + "Để ý rằng commit C3 vẫn nằm đâu đó (đã được làm mờ), và commit C3' là bản \"sao chép\" mà ta dán lên nhánh main.", + "", + "Vấn đề duy nhất bây giờ là nhánh main vẫn chưa được cập nhật, làm luôn cho nóng nào..." + ], + "command": "git rebase main", + "beforeCommand": "git commit; git checkout -b bugFix C1; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Giờ thì ta đã chuyển sang nhánh `main`. Tiếp tục dán nó vào `bugFix` nào..." + ], + "afterMarkdowns": [ + "Đó! Bởi vì `main` là cha ông của `bugFix`, git đơn giản chuyển tham chiếu của nhánh `main` tiến lên." + ], + "command": "git rebase bugFix", + "beforeCommand": "git commit; git checkout -b bugFix C1; git commit; git rebase main; git checkout main" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Để hoàn thành cấp độ này, làm theo hướng dẫn sau", + "", + "* Chuyển sang nhánh mới tên là `bugFix`", + "* Commit một lần", + "* Quay về main và commit lần nữa", + "* Quay trở lại bugFix và rebase sang main", + "", + "Chúc may mắn!" + ] + } + } + ] + },"sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Rebase", + "", + "Drugi način kombiniranja dela med branchi je *rebasing*. Rebasing vzame listo commitov, jih \"skopira\", nato pa jih položi nekam drugam.", + "", + "To se morda sliši komplicirano, ampak prednost rebeasinga je, da se ga lahko uporabi za lepo linearno zaporedje commitov. Commit log / zgodovina repozitorija bo dosti lepša, če je dovoljeno le rebaseanje.", + "", + "Poglejmo to na primeru ..." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Tu imamo spet dva brancha; trenutno izbran je branch bugFix (zvezdica).", + "", + "Radi bi prestavili naše delo iz bugFix direktno na delo iz masterja. Tako bi izgledalo, kot da sta bili ti dve funkcionalnosti razviti zaporedno, v resnici pa sta bili razviti vzporedno.", + "", + "Naredimo sedaj to z `git rebase` ukazom." + ], + "afterMarkdowns": [ + "Super! Sedaj je naše delo iz bugFix brancha na vrhu masterja in imamo lepo zaporedje commitov.", + "", + "Omenimo, da commit C3 še vedno obstaja nekje (v drevesu je zbledel), in C3' je v bistvu \"kopija\", ki smo jo rebaseali na main.", + "", + "Edini problem je, da tudi main ni bil posodobljen, naredimo to sedaj ..." + ], + "command": "git rebase main", + "beforeCommand": "git commit; git checkout -b bugFix C1; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Sedaj smo checkoutani na `main` branchu. Pojdimo in rebaseajmo na `bugFix`..." + ], + "afterMarkdowns": [ + "Tako! Ker je bil `main` prednik `bugFix`, je git enostavno premaknil `main` branch referenco naprej v zgodovini." + ], + "command": "git rebase bugFix", + "beforeCommand": "git commit; git checkout -b bugFix C1; git commit; git rebase main; git checkout main" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Da zaključiš to stopnjo, naredi naslednje:", + "", + "* Checkoutaj nov branch poimenovan `bugFix`", + "* Enkrat commitaj", + "* Pojdi nazaj na main in commitaj ponovno", + "* Ponovno checkoutaj bugFix in ga rebaseaj na main", + "", + "Srečno!" + ] + } + } + ] + }, + "pl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Rebase", + "", + "Drugim sposobem na łączenie naszej pracy między branch-ami jest *rebase*. Rebase zasadniczo pobiera zestaw commit-ów, \"kopiuje\" je i umieszcza w innym miejscu.", + "", + "Chociaż brzmi to zagmatwane, zaletą rebase jest to, że można jej użyć do stworzenia ładnej liniowej sekwencji zatwierdzeń. Rebase sprawi, że historia commit-ów w repozytorium będzie wyglądał na dużo prostszy, ponieważ unika się commit-ów scalających (merge).", + "", + "Zobaczmy to w akcji..." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Tutaj znowu mamy dwa gałęzie (branch-e); zwróć uwagę, że branch bugFix jest aktualnie wybrany (zwróć uwagę, że ma gwiazdkę)", + "", + "Chcielibyśmy przenieść nasze pracę z branch-a bugFix bezpośrednio do branch-a main. W ten sposób wyglądałoby to tak, jakby te dwa zadania były rozwijane sekwencyjnie, podczas gdy w rzeczywistości rozwijano je równolegle.", + "", + "Zróbmy to za pomocą polecenia `git rebase`." + ], + "afterMarkdowns": [ + "Świetnie! Teraz nasz branch bugFix znajduje się tuż nad main i mamy ładną liniową sekwencję zatwierdzeń tj. commit-ów.", + "", + "Zauważ, że commit C3 nadal gdzieś istnieje (ma wyblakły wygląd w drzewie), a commit C3' jest \"kopią\", którą nadpisujemy na main.", + "", + "Jedynym problemem jest to, że main też nie został zaktualizowany, zróbmy to teraz..." + ], + "command": "git rebase main", + "beforeCommand": "git commit; git checkout -b bugFix C1; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Jesteśmy teraz na branch-u `main`. Przejdźmy dalej i zróbmy połączenie rebase z branch-em `bugFix`..." + ], + "afterMarkdowns": [ + "Oto jest! Ponieważ `main` był przodkiem `bugFix`, GIT po prostu przesunął odniesienie do branch-a `main` do przodu w historii." + ], + "command": "git rebase bugFix", + "beforeCommand": "git commit; git checkout -b bugFix C1; git commit; git rebase main; git checkout main" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Aby ukończyć ten poziom, wykonaj następujące czynności:", + "", + "* Przejdź do nowego utworzonego branch-u o nazwie `bugFix`", + "* Zrób commit", + "* Wróć do branch-a main i zrób kolejny commit", + "* Przejdź do bugFix oraz połącz za pomocą rebase z main", + "", + "Powodzenia, misja zakończona!" + ] + } + } + ] } } }; diff --git a/src/levels/mixed/describe.js b/src/levels/mixed/describe.js index 155c0c0a..1eefde4d 100644 --- a/src/levels/mixed/describe.js +++ b/src/levels/mixed/describe.js @@ -1,4 +1,4 @@ -exports.level = { +exports.level = { "goalTreeString": "{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\",\"remoteTrackingBranchID\":null},\"side\":{\"target\":\"C4\",\"id\":\"side\",\"remoteTrackingBranchID\":null},\"bugFix\":{\"target\":\"C7\",\"id\":\"bugFix\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C3\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C3\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C5\"],\"id\":\"C6\"},\"C7\":{\"parents\":[\"C6\"],\"id\":\"C7\"}},\"tags\":{\"v0\":{\"target\":\"C0\",\"id\":\"v0\",\"type\":\"tag\"},\"v1\":{\"target\":\"C3\",\"id\":\"v1\",\"type\":\"tag\"}},\"HEAD\":{\"target\":\"bugFix\",\"id\":\"HEAD\"}}", "solutionCommand": "git commit ", "startTree": "{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\",\"remoteTrackingBranchID\":null},\"side\":{\"target\":\"C4\",\"id\":\"side\",\"remoteTrackingBranchID\":null},\"bugFix\":{\"target\":\"C6\",\"id\":\"bugFix\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C3\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C3\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C5\"],\"id\":\"C6\"}},\"tags\":{\"v0\":{\"target\":\"C0\",\"id\":\"v0\",\"type\":\"tag\"},\"v1\":{\"target\":\"C3\",\"id\":\"v1\",\"type\":\"tag\"}},\"HEAD\":{\"target\":\"bugFix\",\"id\":\"HEAD\"}}", @@ -8,25 +8,33 @@ "de_DE": "Git Describe", "ja" : "Git Describe", "es_AR": "Git Describe", + "es_ES": "Git Describe", "pt_BR": "Git Describe", + "gl" : "Git Describe", "zh_TW": "git describe", "zh_CN": "Git Describe", "ru_RU": "Git describe", "ko" : "Git describe(묘사)", - "uk" : "Git Describe" + "uk" : "Git Describe", + "vi": "Git Describe(mô tả)", + "sl_SI": "Git Describe" }, "hint": { "en_US": "Just commit once on bugFix when you're ready to move on", - "fr_FR": "Faites un commit sur bugFix quand vous êtes pret", + "fr_FR": "Faites un commit sur bugFix quand vous êtes prêt", "de_DE": "Committe nur einmal auf bugFix, wenn du soweit bist", "ja" : "次に進む準備が整ったなら、bugFixに対して一回commitしてください", "es_AR": "Simplemente commiteá una vez en bugFix cuando estés listo para seguir", + "es_ES": "Simplemente crea un commit en la rama bugFix cuando estés listo para seguir", "pt_BR": "Simplesmente commite uma vez em bugFix quando quiser parar de experimentar", + "gl" : "Simplemente fai commit en bugFix cando estés listo para continuar.", "zh_TW": "當你要移動的時候,只要在 bugFix 上面 commit 就好了", - "zh_CN": "在 bugFix 上面提交一次就可以了", + "zh_CN": "当你准备好时,在 bugFix 分支上面提交一次就可以了", "ru_RU": "Когда закончишь, просто сделай commit", "ko" : "다음으로 넘어가고 싶으면 bugFix를 한번 커밋하면 됩니다.", - "uk" : "Просто зроби один коміт в bugFix коли ти будеш готовий іти далі" + "uk" : "Просто зроби один коміт в bugFix коли ти будеш готовий іти далі", + "vi": "Đơn giản là hãy commit một lẩn ở bugFix là xong rồi", + "sl_SI": "Commitaj enkrat na bugFix, ko boš pripravljen za nadaljevanje." }, "startDialog": { "en_US": { @@ -68,7 +76,7 @@ "Let's look at a quick example. For this tree below:" ], "afterMarkdowns": [ - "The command `git describe master` would output:", + "The command `git describe main` would output:", "", "`v1_2_gC2`", "", @@ -102,7 +110,7 @@ "", "Parce ce que les tags sont de très bonnes références dans le code, git à une commande pour *décrire* (describe) la différence entre le commit et le tag le plus récent. Cette commande s'appelle `git describe` !", "", - "Git describe peut vous aider lorsque vous vous êtes beaucoup déplacé ; cela peut arriver après un git bisect (chercher l'apparition d'un bug) ou lorsque vous revenez de vacances après 3 semaines sur l'ordinateur d'un collègue." + "Git describe peut vous aider lorsque vous vous êtes beaucoup déplacé; cela peut arriver après un git bisect (chercher l'apparition d'un bug) ou lorsque vous revenez de vacances après 3 semaines sur l'ordinateur d'un collègue." ] } }, @@ -114,7 +122,7 @@ "", "`git describe `", "", - "où `` est un n'importe quelle chose que git peut résoudre en un commit. Si vous ne specifiez pas de ref, `HEAD` est pris par défault.", + "où `` est un n'importe quelle chose que git peut résoudre en un commit. Si vous ne spécifiez pas de ref, `HEAD` est pris par défaut.", "", "Le résultat de la commande ressemble à :", "", @@ -128,10 +136,10 @@ "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Regardons un petit exemple. Prennons cet arbre :" + "Regardons un petit exemple. Prenons cet arbre :" ], "afterMarkdowns": [ - "La commande`git describe master` donne le résultat :", + "La commande`git describe main` donne le résultat :", "", "`v1_2_gC2`", "", @@ -194,7 +202,7 @@ "讓我們來看一個例子,對於下面的 tree:" ], "afterMarkdowns": [ - "`git describe master` 會輸出:", + "`git describe main` 會輸出:", "", "`v1_2_gC2`", "", @@ -259,7 +267,7 @@ "让我们来看一个例子,对于下面的提交树:" ], "afterMarkdowns": [ - "`git describe master` 会输出:", + "`git describe main` 会输出:", "", "`v1_2_gC2`", "", @@ -322,7 +330,7 @@ "Veamos un ejemplo breve. Para este árbol de commits:" ], "afterMarkdowns": [ - "El comando `git describe master` mostraría:", + "El comando `git describe main` mostraría:", "", "`v1_2_gC2`", "", @@ -346,6 +354,69 @@ } ] }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Git Describe", + "", + "Como los tags sirven tanto para marcar \"hitos\" en el código, git tiene un comando para *describir* (_describe_) dónde estás relativo al \"hito\" más cercano (digamos, \"tag\"). Y ese comamndo se llama ¡`git describe`!", + "", + "Git describe puede ayudarte a saber dónde estás después de que te hayas movido varios commits hacia adelante o atrás en la historia. Esto puede pasarte después de que termines un git bisect (una búsqueda que te ayuda a debuggear problemas) o cuando te sientas delante de la computadora de un compañero de trabajo que acaba de volver de unas vacaciones." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Git describe tiene la siguiente forma:", + "", + "`git describe `", + "", + "Donde `` es cualquier cosa que git puede resolver a un commit. Si no especificas ninguna referencia, git simplemente usa el commit en el que estás parado ahora (`HEAD`).", + "", + "La salida de ese comando se ve así:", + "", + "`__g`", + "", + "Donde `tag` es el tag más cercano en la historia, `numCommits` dice a cuántos commits de ese tag estás, y `` es el hash del commit que estás describiendo." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Veamos un ejemplo breve. Para este árbol de commits:" + ], + "afterMarkdowns": [ + "El comando `git describe main` mostraría:", + "", + "`v1_2_gC2`", + "", + "Mientras que `git describe side` debería mostrar:", + "", + "`v2_1_gC4`" + ], + "command": "git tag v2 C3", + "beforeCommand": "git commit; go -b side HEAD~1; gc; gc; git tag v1 C0" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "¡Eso es prácticamente todo lo que hay sobre git describe! Prueba con algunas referencias en este nivel para familiarizarte con el comando.", + "", + "Cuando estés listo, crea un commit para terminar el nivel. Te estamos dando una gratis :P" + ] + } + } + ] + }, "pt_BR": { "childViews": [ { @@ -385,7 +456,7 @@ "Vejamos um exemplo rápido. Para a árvore abaixo:" ], "afterMarkdowns": [ - "O comando `git describe master` daria a saída:", + "O comando `git describe main` daria a saída:", "", "`v1_2_gC2`", "", @@ -409,6 +480,69 @@ } ] }, + "gl" : { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Git Describe", + "", + "Como as tags fan a función de \"áncora\" no repositorio, Git ten un comando para *describir* ónde podes estar ti en relación á \"áncora\" (tag) máis próxima. Ese comando chámase `git describe`!", + "", + "Git describe pode axudar a recuperar a túa posición despois de mover moitos commits para atrás ou para adiante na historia; esto pode suceder depois de que fagas un git bisect (unha búsqueda para atopar erros) ou cando te sentas no ordenador dun colega que chegou das vacacións." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Git describe lánzase do seguinte xeito:", + "", + "`git describe `", + "", + "Onde `` é qualquera cousa que git poida resolver como unha referencia a un commit. Se non especificas a ref, git usará o commit actual no que se esté traballando (`HEAD`).", + "", + "A resposta do comando é algo semellante a esto:", + "", + "`__g`", + "", + "Onde `tag` é a tag anterior máis próxima na historia, `numCommits` é o número de commits de distancia ó tag, e `` é o hash do commit no que estamos." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Vexamos un exemplo rápido. Para a árbore de abaixo:" + ], + "afterMarkdowns": [ + "O comando `git describe main` daría a saída:", + "", + "`v1_2_gC2`", + "", + "Mentres que `git describe side` daría:", + "", + "`v2_1_gC4`" + ], + "command": "git tag v2 C3", + "beforeCommand": "git commit; go -b side HEAD~1; gc; gc; git tag v1 C0" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "¡Básicamente é iso do que trata git describe! Intenta descubrir algúns locais da árbore para sentir como se comporta o comando.", + "", + "Cando estés listo, fai un commit para que o nivel remate. Esa é a gracia." + ] + } + } + ] + }, "de_DE": { "childViews": [ { @@ -417,9 +551,9 @@ "markdowns": [ "### Git Describe", "", - "Weil Tags so super als \"Anker\" im Repository dienen können bietet Git einen Befehl um zu *beschreiben* wo du dich relativ zum nächsten \"Anker\" (also Tag) befindest. Und der heißt `git describe`.", + "Weil Tags so super als \"Anker\" im Repository dienen können, bietet Git einen Befehl um zu *beschreiben*, wo du dich relativ zum nächsten \"Anker\" (also Tag) befindest. Und der heißt `git describe`.", "", - "Er hilft dir dabei, dir einen Überblick zu verschaffen nachdem du viele Commits im Log zurück- oder vorgegangen bist; das kann vorkommen nachdem du ein `git bisect` (eine Fehlersuche) abgeschlossen hast oder wenn du dich an den Rechner eines Kollegen setzt, der gerade aus dem Urlaub gekommen ist." + "Er hilft dir dabei, dir einen Überblick zu verschaffen nachdem du viele Commits im Log zurück- oder vorgegangen bist; das kann vorkommen, nachdem du ein `git bisect` (eine Fehlersuche) abgeschlossen hast oder wenn du dich an den Rechner eines Kollegen setzt, der gerade aus dem Urlaub gekommen ist." ] } }, @@ -431,13 +565,15 @@ "", "`git describe `", "", - "Dabei ist `` jeder beliebige Name, der einem Commit zugeordnet ist (Branch, Tag etc). Wenn du keinen angibst benutzt Git `HEAD`, also den aktuellen Checkout.", + "Dabei ist `` jeder beliebige Name, der einem Commit zugeordnet ist (Branch, Tag etc). Wenn du keinen angibst, benutzt Git `HEAD`, also den aktuellen Checkout.", "", "Die Befehlsausgabe sieht so aus:", "", "`__g`", "", - "`` ist dabei der nächstliegende Tag in den Vorgänger-Commits, `` zeigt an, wieviele Commits dieses Tag entfernt ist und `` ist das SHA des Commits, auf den das Tag zeigt." + "`` ist dabei der nächstliegende Tag in den Vorgänger-Commits, `` zeigt an, wieviele Commits dieses Tag entfernt ist und `` ist das SHA des Commits, auf den HEAD zeigt.", + "", + "**Achtung**: `` und `` erscheint nur, wenn HEAD nicht auf ein Tag zeigt. `git describe` verarbeitet standardmäßig nur annotierte Tags. Um nicht annotierte Tags zu sehen, verwende bitte `git describe --tags`." ] } }, @@ -448,7 +584,7 @@ "Schauen wir uns das schnell an einem Beispiel an. Für den folgenden Baum:" ], "afterMarkdowns": [ - "Der Befehl `git describe master` würde folgendes ausgeben:", + "Der Befehl `git describe main` würde folgendes ausgeben:", "", "`v1_2_gC2`", "", @@ -511,7 +647,7 @@ "軽い例を見てみましょう。この木においての例は以下のようになります:" ], "afterMarkdowns": [ - "コマンド`git describe master`の結果は以下のようになります:", + "コマンド`git describe main`の結果は以下のようになります:", "", "`v1_2_gC2`", "", @@ -543,7 +679,7 @@ "markdowns": [ "### Git Describe", "", - "Теги являются прекрасными ориентирами в истории изменений, поэтому в git есть команда, которая показывает, как далеко текущее состоянии от ближайшего тега. И эта команда называется `git describe`", + "Теги являются прекрасными ориентирами в истории изменений, поэтому в git есть команда, которая показывает, как далеко текущее состояние от ближайшего тега. И эта команда называется `git describe`", "", "Git describe помогает сориентироваться после отката на много коммитов по истории изменений. Такое может случиться, когда вы сделали `git bisect` или если вы недавно вернулись из отпуска =)" ] @@ -574,7 +710,7 @@ "Посмотрим на простой пример. Для дерева, показанного ниже:" ], "afterMarkdowns": [ - "Команда `git describe master` выведет:", + "Команда `git describe main` выведет:", "", "`v1_2_gC2`", "", @@ -598,7 +734,7 @@ } ] }, - "ko": { + "ko": { "childViews": [ { "type": "ModalAlert", @@ -637,7 +773,7 @@ "간단한 예제를 확인해 봅시다. 아래의 트리에서:" ], "afterMarkdowns": [ - "`git describe master` 명령은 다음을 출력합니다:", + "`git describe main` 명령은 다음을 출력합니다:", "", "`v1_2_gC2`", "", @@ -700,7 +836,7 @@ "Розгляньмо короткий приклад. Для дерева нижче:" ], "afterMarkdowns": [ - "Команда `git describe master` виведе:", + "Команда `git describe main` виведе:", "", "`v1_2_gC2`", "", @@ -723,6 +859,132 @@ } } ] + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Mô tả của Git", + "", + "Bởi gì thẻ đóng vai trò như là \"mỏ neo\" trên cây lịch sử rất tốt rồi, git cũng có lệnh để *mô tả* tương quan của bạn dến vị trí \"mỏ neo\" (thẻ) gần nhất. Và đó là `git describe`!", + "", + "`git descripe` có thể giúp bạn định hướng sau khi dịch chuyển qua lại nhiều lần trên cây lịch sử; đặc biệt là sau khi sử dụng `git bisect` (công cụ tìm kiếm lỗi của git) hoặc khi sử dụng máy của đồng nghiệp mới đi nghỉ mát về." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Cú pháp sử dụng Git describe như sau:", + "", + "`git describe `", + "", + "Trong đó `` là bất kỳ thứ gì mà git có thể dùng để xác định commit. Nếu bạn không chỉ định tham chiếu, git sẽ dùng vị trí hiện tại của bạn (`HEAD`).", + "", + "Đầu ra của câu lệnh sẽ như sau:", + "", + "`__g`", + "", + "Trong đó `` là thẻ tổ tiên gần nhất, `` là số lượng commit tính từ tham chiếu đến thẻ, và `` là mã băm của commit được mô tả." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Cùng xem nhanh một ví dụ trên cây lịch sử phía dưới:" + ], + "afterMarkdowns": [ + "Câu lệnh `git describe main` sẽ cho kết quả:", + "", + "`v1_2_gC2`", + "", + "Trong khi `git describe side` sẽ cho kết quả:", + "", + "`v2_1_gC4`" + ], + "command": "git tag v2 C3", + "beforeCommand": "git commit; go -b side HEAD~1; gc; gc; git tag v1 C0" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Từng đó thông tin là khá đủ về git describe! Hãy thử dùng `git describe` trên vài vị trí để hiểu về lệnh này.", + "", + "Một khi bạn đã sẵn sàng thì chỉ cần commit 1 lần là qua bài này. Bài này dễ chơi rồi nhé :P" + ] + } + } + ] + }, + "sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Git Describe", + "", + "Ker tagi služijo kot tako odlična \"sidra\" v kodi, ima git ukaz za *opis* kje si, relativno glede na najbližje \"sidro\" (aka tag). Temu ukazu se reče `git describe`!", + "", + "Git describe se ti lahko pomaga orientirati, če si premikal veliko commitov naprej in nazaj po zgodovini; to se lahko zgodi, če si končal git bisekcijo (iskanje kot debuggiranje) ali če se usedeš za sodelavčev računalnik, ko je ravno prišel z dopusta." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Git describe izgleda takole:", + "", + "`git describe `", + "", + "Kjer je `` karkoli kar lahko git prepozna kot commit. Če ne podaš ref-a, git uporabi mesto, kjer si trenutno checkoutan (`HEAD`).", + "", + "Izpis ukaza je sledeč:", + "", + "`__g`", + "", + "Kjer je `tag` najbližji prednik v zgodovini, `numCommits` je število commitov oddaljenosti tag-a in `` je hash commita, ki ga opisujemo." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Poglejmo hiter primer. Za drevo spodaj:" + ], + "afterMarkdowns": [ + "Bi ukaz `git describe main` izpisal:", + "", + "`v1_2_gC2`", + "", + "Ukaz `git describe side` pa bi vrnil:", + "", + "`v2_1_gC4`" + ], + "command": "git tag v2 C3", + "beforeCommand": "git commit; go -b side HEAD~1; gc; gc; git tag v1 C0" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "To je približno vse, kar se tiče git describe-a! Poizkusi za občutek opisati nekaj lokacij v tej stopnji.", + "", + "Ko si pripravljen, samo enkrat commitaj, da zaključiš stopnjo. Tole ti častimo :P" + ] + } + } + ] } } }; diff --git a/src/levels/mixed/grabbingOneCommit.js b/src/levels/mixed/grabbingOneCommit.js index b1096188..7408627c 100644 --- a/src/levels/mixed/grabbingOneCommit.js +++ b/src/levels/mixed/grabbingOneCommit.js @@ -11,33 +11,41 @@ exports.level = { "git revert": true }, "goalTreeString": "%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C4%27%22%2C%22id%22%3A%22master%22%7D%2C%22debug%22%3A%7B%22target%22%3A%22C2%22%2C%22id%22%3A%22debug%22%7D%2C%22printf%22%3A%7B%22target%22%3A%22C3%22%2C%22id%22%3A%22printf%22%7D%2C%22bugFix%22%3A%7B%22target%22%3A%22C4%27%22%2C%22id%22%3A%22bugFix%22%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C4%22%3A%7B%22parents%22%3A%5B%22C3%22%5D%2C%22id%22%3A%22C4%22%7D%2C%22C4%27%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C4%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%7D", - "solutionCommand": "git checkout master;git cherry-pick C4", + "solutionCommand": "git rebase -i main --solution-ordering C4; git rebase bugFix main", "startTree": "{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\"},\"debug\":{\"target\":\"C2\",\"id\":\"debug\"},\"printf\":{\"target\":\"C3\",\"id\":\"printf\"},\"bugFix\":{\"target\":\"C4\",\"id\":\"bugFix\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C2\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C3\"],\"id\":\"C4\"}},\"HEAD\":{\"target\":\"bugFix\",\"id\":\"HEAD\"}}", "name": { - "ko": "딱 한개의 커밋만 가져오기", + "ko": "딱 한 개의 커밋만 가져오기", "en_US": "Grabbing Just 1 Commit", "fr_FR": "Choisir seulement 1 commit", "de_DE": "Einen Commit pflücken", "es_AR": "Tomando un único commit", + "es_ES": "Tomando un único commit", "pt_BR": "Pegando um único commit", + "gl" : "Escollendo un único commit", "ja": "一つのコミットのみを取得", "zh_CN": "只取一个提交记录", "zh_TW": "只取一個 commit", "ru_RU": "Выберем один коммит.", - "uk": "Вибираємо всього один коміт" + "uk": "Вибираємо всього один коміт", + "vi": "Chỉ lấy 1 commit", + "sl_SI": "Izbiranje Samo Enega Commita" }, "hint": { "en_US": "Remember, interactive rebase or cherry-pick is your friend here", "de_DE": "Vergiss nicht: hier kommst du mit interaktivem Rebase oder Cherry-Picking weiter", "fr_FR": "Souvenez-vous, les rebases interactifs ou cherry-pick sont vos amis ici.", "es_AR": "Acordate, el rebase interactivo o cherry-pick son tus amigos acá", + "es_ES": "Recuerda, el rebase interactivo y el cherry-pick son tus amigos", "pt_BR": "Lembre-se, o rebase interativo ou o cherry-pick são seus amigos aqui", + "gl" : "Recorda, o rebase interativo ou cherry-pick é un dos teus colegas aquí", "ja": "このレベルではインタラクティブモードのrebaseやcherry-pickがクリアのカギです", "ko": "대화식 리베이스(rebase -i)나 or 체리픽(cherry-pick)을 사용하세요", "zh_CN": "你有两个朋友,cherry-pick 和 rebase -i", "zh_TW": "記住,使用互動式的 rebase 或者 cherry-pick 會很有幫助", "ru_RU": "Не забывай, что интерактивный rebase и cherry-pick – это твои друзья!", - "uk": "Не забувай, що інтерактивний rebase та cherry-pick -- це твої друзі!" + "uk": "Не забувай, що інтерактивний rebase та cherry-pick -- це твої друзі!", + "vi": "Hãy nhớ 2 anh bạn tương tác rebase và cherry-pick!", + "sl_SI": "Pomni, interaktivni rebase ali cherry-pick sta tu tvoja prijatelja." }, "startDialog": { "en_US": { @@ -52,7 +60,7 @@ exports.level = { "", "All of these debugging / print statements are in their own commits. Finally I track down the bug, fix it, and rejoice!", "", - "Only problem is that I now need to get my `bugFix` back into the `master` branch. If I simply fast-forwarded `master`, then `master` would get all my debug statements which is undesirable. There has to be another way..." + "Only problem is that I now need to get my `bugFix` back into the `main` branch. If I simply fast-forwarded `main`, then `main` would get all my debug statements which is undesirable. There has to be another way..." ] } }, @@ -73,7 +81,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "This is a later level so we will leave it up to you to decide which command you want to use, but in order to complete the level, make sure `master` receives the commit that `bugFix` references." + "This is a later level so we will leave it up to you to decide which command you want to use, but in order to complete the level, make sure `main` receives the commit that `bugFix` references." ] } } @@ -91,7 +99,7 @@ exports.level = { "", "Tous ces debug se retrouvent dans une branche particulière. Je trouve le bug et le répare, comme toujours !", "", - "Le seul problème c'est que je ne peux pas faire de merge ou rebase, car tous ces commits de debug seront dans le master. Il doit y avoir une autre façon..." + "Le seul problème c'est que je ne peux pas faire de merge ou rebase, car tous ces commits de debug seront dans le main. Il doit y avoir une autre façon..." ] } }, @@ -110,7 +118,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "C'est un niveau avancé, donc à vous de choisir quelle commande utiliser, mais pour réussir ce niveau, assurez-vous que `master` reçoive le même commit que `bugFix` référence." + "C'est un niveau avancé, donc à vous de choisir quelle commande utiliser, mais pour réussir ce niveau, assurez-vous que `main` reçoive le même commit que `bugFix` référence." ] } } @@ -128,7 +136,7 @@ exports.level = { "", "Todas estas cosas de imprimir y debuggear estan en su propia rama. Finalmente encuentro el problema, lo soluciono, ¡y disfruto!", "", - "El único problema es que ahora necesito llevar mi `bugFix` a la rama `master`. Si simplemente fast-forwardeo `master`, entonces `master` va a tener todos mis agregados de debugging, que es indeseado. Tiene que haber otro modo..." + "El único problema es que ahora necesito llevar mi `bugFix` a la rama `main`. Si simplemente fast-forwardeo `main`, entonces `main` va a tener todos mis agregados de debugging, que es indeseado. Tiene que haber otro modo..." ] } }, @@ -149,7 +157,46 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Este es un nivel más avanzado, así que está en vos decidir cuál de los dos comandos querés usar, pero para completar el nivel asegurate de que `master` recibe el commit que `bugFix` referencia." + "Este es un nivel más avanzado, así que está en vos decidir cuál de los dos comandos querés usar, pero para completar el nivel asegurate de que `main` recibe el commit que `bugFix` referencia." + ] + } + } + ] + }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Commits localmente stackeados", + "", + "Esta es una escena que suele pasar cuando uno desarrolla: estoy tratando de encontrar un bug bastante escurridizo. Para ayudar en mi tarea de detective, agrego un par de comandos de debug, y algunas sentencias para imprimir el estado de mi sistema.", + "", + "Todas estas cosas de imprimir y debuggear estan en su propia rama. Finalmente encuentro el problema, lo soluciono, ¡y disfruto!", + "", + "El único problema es que ahora necesito llevar mi `bugFix` a la rama `main`. Si simplemente fast-forwardeo `main`, entonces `main` va a tener todos mis agregados de debugging, lo cual no es deseable. Tiene que haber otro modo..." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Necesitamos decirle a git que sólo copie uno de los commits. Esto es tal como los niveles anteriores de mover commits por ahí -- podemos usar los mismos comandos:", + "", + "* `git rebase -i`", + "* `git cherry-pick`", + "", + "Para conseguir este resultado." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Este es un nivel más avanzado, así que debes decidir cuál de los dos comandos quieres usar, pero para completar el nivel asegurate de que `main` recibe el commit que `bugFix` referencia." ] } } @@ -167,7 +214,7 @@ exports.level = { "", "Todos esses comandos de debug e mensagens estão em seus próprios ramos. Finalmente eu encontro o bug, corrijo, e me regozijo!", "", - "O único problema é que agora eu preciso devolver o meu `bugFix` ao ramo `master`. Se eu simplesmente der um fast-forward no `master`, então o `master` terminará contendo todos os comandos de debug, o que é indesejável. Deve existir alguma outra forma..." + "O único problema é que agora eu preciso devolver o meu `bugFix` ao ramo `main`. Se eu simplesmente der um fast-forward no `main`, então o `main` terminará contendo todos os comandos de debug, o que é indesejável. Deve existir alguma outra forma..." ] } }, @@ -188,7 +235,46 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Este é um nível avançado, então vamos deixar para você a decisão de qual comando usar, mas para completar este nível, certifique-se de que o `master` receba o commit referenciado por `bugFix`." + "Este é um nível avançado, então vamos deixar para você a decisão de qual comando usar, mas para completar este nível, certifique-se de que o `main` receba o commit referenciado por `bugFix`." + ] + } + } + ] + }, + "gl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Commits apilados localmente", + "", + "Aquí estamos nunha situación que acontece de cotio con desenvolvedores: Estou intentando atopar un erro, mais é escorredizo. Para axudar ó meu traballo de detective, eu coloco algúns comandos de debug e prints.", + "", + "¡Todos esos comandos de debug e mensaxes están nas súas ramas propias. Finalmente eu atopo o erro, arránxoo e reorganizo!", + "", + "O único problema é que agora eu preciso devolver o meu `bugFix` á rama `main`. Se eu fixera simplemente un fast-forward en `main`, entón o `main` rematará contendo tódolos comandos de debug, o que é indesexable. Debe existir algunha outra forma..." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Precisamos decirlle a git que copie só os commits que nos interesa. Esta situación é exatamente a mesma dos niveis anteriores respecto de como mover o traballo -- podemos usar os mesmos comandos:", + "", + "* `git rebase -i`", + "* `git cherry-pick`", + "", + "Para acadar o objetivo." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Este é un nivel avanzado, entón imos deixarche a decisión de qué comando empregar, pero para completar este nivel, asegurate de que a rama `main` colla o commit referenciado por `bugFix`." ] } } @@ -202,11 +288,11 @@ exports.level = { "markdowns": [ "## Lokale Commit-Haufen", "", - "Folgende Situation habe ich beim Entwickeln des öfteren: ich bin auf der Suche nach einem Bug, aber er ist echt schwer zu finden. Um ihm auf die Spur zu kommen schreibe ich mehrere Debug-Kommandos und print-Befehle in den Code.", + "Folgende Situation habe ich beim Entwickeln des Öfteren: ich bin auf der Suche nach einem Bug, aber er ist echt schwer zu finden. Um ihm auf die Spur zu kommen schreibe ich mehrere Debug-Kommandos und print-Befehle in den Code.", "", "Die committe ich auch immer wieder, je weiter die Suche mich trägt; natürlich in einem lokalen Branch. Schließlich finde ich den Bug, fixe ihn und freue mich!", "", - "Einziges Problem ist, dass ich diesen `bugFix` jetzt zurück in den `master` kriegen muss. Wenn ich einfach den `master` vorspule oder meinen Branch hinein merge, bekäme der `master` auch die ganzen Debug-Befehle, was nicht gewünscht ist. Das muss anders gehen ..." + "Einziges Problem ist, dass ich diesen `bugFix` jetzt zurück in den `main` kriegen muss. Wenn ich einfach den `main` vorspule oder meinen Branch hinein merge, bekäme der `main` auch die ganzen Debug-Befehle, was nicht gewünscht ist. Das muss anders gehen ..." ] } }, @@ -226,7 +312,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Da dies ein späterer Level ist überlasse ich es dir zu entscheiden, welchen Befehl du benutzen willst. Aber um da Level zu schaffen musst du irgendwie sicherstellen, dass `master` den Commit bekommt, auf den `bugFix` zeigt." + "Da dies ein späterer Level ist überlasse ich es dir zu entscheiden, welchen Befehl du benutzen willst. Aber um das Level zu schaffen musst du irgendwie sicherstellen, dass `main` den Commit bekommt, auf den `bugFix` zeigt." ] } } @@ -245,7 +331,7 @@ exports.level = { "", "これらのデバッグ用のコードはバグ修正用のブランチにコミットされています。そしてついにバグの原因を突き止めて、修正した!やった!", "", - "あとは`bugFix`ブランチを`master`ブランチに統合できればOK。そこで単純に`master`をfast-forwardすればよいかというと、それでは`master`ブランチの中にデバッグ用のコードも混入してしまいます。" + "あとは`bugFix`ブランチを`main`ブランチに統合できればOK。そこで単純に`main`をfast-forwardすればよいかというと、それでは`main`ブランチの中にデバッグ用のコードも混入してしまいます。" ] } }, @@ -268,7 +354,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "後半の章ですのでどう解決するかをもう自分で考えることができると思います。このレベルをクリアするためには、`bugFix`が持っているコミットを`master`ブランチが受け取る必要がある点には注意してください。" + "後半の章ですのでどう解決するかをもう自分で考えることができると思います。このレベルをクリアするためには、`bugFix`が持っているコミットを`main`ブランチが受け取る必要がある点には注意してください。" ] } } @@ -286,7 +372,7 @@ exports.level = { "", "这些调试和打印语句都在它们各自的提交记录里。最后我终于找到了造成这个 Bug 的根本原因,解决掉以后觉得沾沾自喜!", "", - "最后就差把 `bugFix` 分支里的工作合并回 `master` 分支了。你可以选择通过 fast-forward 快速合并到 `master` 分支上,但这样的话 `master` 分支就会包含我这些调试语句了。你肯定不想这样,应该还有更好的方式……" + "最后就差把 `bugFix` 分支里的工作合并回 `main` 分支了。你可以选择通过 fast-forward 快速合并到 `main` 分支上,但这样的话 `main` 分支就会包含我这些调试语句了。你肯定不想这样,应该还有更好的方式……" ] } }, @@ -307,7 +393,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "由于我们刚刚闯过类似的关卡,所以要不要再尝试一次就看你自己了。但是如果你想试一把的话,确保 `master` 分支能得到 `bugFix` 分支上的相关提交。" + "由于我们刚刚闯过类似的关卡,所以要不要再尝试一次就看你自己了。但是如果你想试一把的话,确保 `main` 分支能得到 `bugFix` 分支上的相关提交。" ] } } @@ -325,7 +411,7 @@ exports.level = { "", "所有的這些 debug 的指令都只在 `bugFix` 這個 branch 裡面。最後我終於找到這個 bug,並且 fix 掉它,接著撒花慶祝一下!", "", - "現在唯一的問題就是要把我在 `bugFix` branch 裡面所做的修改 merge 回 `master` branch。我可以簡單地透過 fast-forward 來 merge ,但這樣的話 `master` branch 就會包含這些含有 debug 指令的 commit 了。我相信一定有其它方法..." + "現在唯一的問題就是要把我在 `bugFix` branch 裡面所做的修改 merge 回 `main` branch。我可以簡單地透過 fast-forward 來 merge ,但這樣的話 `main` branch 就會包含這些含有 debug 指令的 commit 了。我相信一定有其它方法..." ] } }, @@ -346,7 +432,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "這一個關卡是比較後面的關卡,你可以隨意決定你要選擇使用哪個指令,但是 `bugFix` 所指向的那個 commit 一定要可以被 `master` branch 包含到。" + "這一個關卡是比較後面的關卡,你可以隨意決定你要選擇使用哪個指令,但是 `bugFix` 所指向的那個 commit 一定要可以被 `main` branch 包含到。" ] } } @@ -360,11 +446,11 @@ exports.level = { "markdowns": [ "## 로컬에 쌓인 커밋들", "", - "개발중에 종종 이런 상황이 생깁니다: 잘 띄지 않는 버그를 찾아서 해결하려고, 어떤 부분의 문제인지를 찾기 위해 디버그용 코드와 화면에 정보를 프린트하는 코드 몇 줄 넣습니다. ", + "개발 중에 종종 이런 상황이 생깁니다: 눈에 잘 띄지 않는 버그를 찾아서 해결하려고, 어떤 부분의 문제인지를 찾기 위해 디버그용 코드와 화면에 정보를 프린트하는 코드 몇 줄 넣습니다. ", "", "디버깅용 코드나 프린트 명령은 그 브랜치에 들어있습니다. 마침내 버그를 찾아서 고쳤고, 원래 작업하는 브랜치에 합치면 됩니다!", "", - "이제 `bugFix`브랜치의 내용을 `master`에 합쳐 넣으려 하지만, 한 가지 문제가 있습니다. 그냥 간단히 `master`브랜치를 최신 커밋으로 이동시킨다면(fast-forward) 그 불필요한 디버그용 코드들도 함께 들어가 버린다는 문제죠." + "이제 `bugFix`브랜치의 내용을 `main`에 합쳐 넣으려 하지만, 한 가지 문제가 있습니다. 그냥 간단히 `main`브랜치를 최신 커밋으로 이동시킨다면(fast-forward) 그 불필요한 디버그용 코드들도 함께 들어가 버린다는 문제죠." ] } }, @@ -387,7 +473,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "이번 레벨을 통과하기 위해 어떤 방법을 쓰시든 자유입니다만, `master`브랜치가 `bugFix` 브랜치의 커밋을 일부 가져오게 해주세요." + "이번 레벨을 통과하기 위해 어떤 방법을 쓰시든 자유입니다만, `main`브랜치가 `bugFix` 브랜치의 커밋을 일부 가져오게 해주세요." ] } } @@ -403,7 +489,7 @@ exports.level = { "", "Каждая отладочная команда (команды) вывода находится в своём коммите. В итоге мы нашли ошибку, исправили её и порадовались!", "", - "Но проблема в том, что мы хотим добавить в `master` только исправление ошибки из ветки `bugFix`. Если мы воспользуемся простым fast-forward, то в `master` попадут также отладочные команды. Должен быть другой способ..." + "Но проблема в том, что мы хотим добавить в `main` только исправление ошибки из ветки `bugFix`. Если мы воспользуемся простым fast-forward, то в `main` попадут также отладочные команды. Должен быть другой способ..." ] } }, @@ -424,7 +510,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "В этом уровне тебе решать, какую команду использовать, но чтобы закончить уровень, убедись, что в мастер попал коммит, на который ссылается `bugFix`" + "В этом уровне тебе решать, какую команду использовать, но чтобы закончить уровень, убедись, что в мастер попал коммит, на который ссылается `bugFix`." ] } } @@ -442,7 +528,7 @@ exports.level = { "", "Всі ці команди для відлагодження та виводу данних знаходяться в своїх власних комітах. Врешті-решт я знаходжу баг, фікшу його та щиро радію!", "", - "От тільки лишається проблема, що потрібно мій фікс перенести з `bugFix` назад в гілку `master`. Якщо я просто зроблю фастфорвард (fast-forwarded) в `master`, тоді в `master` потраплять всі мої println'и, що є зайвим. Має бути інший шлях..." + "От тільки лишається проблема, що потрібно мій фікс перенести з `bugFix` назад в гілку `main`. Якщо я просто зроблю фастфорвард (fast-forwarded) в `main`, тоді в `main` потраплять всі мої println'и, що є зайвим. Має бути інший шлях..." ] } }, @@ -463,7 +549,85 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "На цьому рівні тобі вирішувати якими командами користуватися, але щоб пройти цей рівень, впевнись що в `master` потрапить коміт, на який посилається `bugFix`." + "На цьому рівні тобі вирішувати якими командами користуватися, але щоб пройти цей рівень, впевнись що в `main` потрапить коміт, на який посилається `bugFix`." + ] + } + } + ] + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Commit xếp chồng tại địa phương", + "", + "Có tình huống thế này thường hay xảy ra trong quá trình phát triển: Tôi dang cố dò lỗi nhưng mà nó lại khá là trúc trắc. Để hỗ trợ cho việc này, thêm vào vài dòng lệnh gỡ lỗi và lệnh in.", + "", + "Mấy lệnh gỡ lỗi và in này nằm yên trong commit của chúng. Cuối cùng thì tôi cũng tìm ra lỗi, gỡ xong, ngon rồi!", + "", + "Bây giờ thì lại phải đưa `bugFix` trở về nhánh `main`. Nếu mà đơn giản dùng fast-forwarded lên `main`, thì `main` lại có tất cả các lệnh gỡ lỗi kia(chẳng muốn chút nào). Phải có cách khác chứ nhỉ..." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Ta cần phải bảo git chỉ sao chép 1 commit thôi. Điều này giống với cấp độ trước về điều chỉnh vị trí -- ta có thể dùng các câu lệnh tương tự:", + "", + "* `git rebase -i`", + "* `git cherry-pick`", + "", + "Để đạt được mục tiêu này." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Bây giờ là cấp độ cao hơn rồi nên bạn hãy tự quyết định nên dùng câu lệnh nào, nhưng để hoàn thành được cấp độ, hãy đàm bảo rằng `main` nhận được commit mà `bugFix` tham chiếu tới." + ] + } + } + ] + }, + "sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Lokalno naloženi commiti", + "", + "Tu je razvijalska situacija, ki se zgodi pogosto: Hočem najti bug, ampak se kar izmika. V pomoč mojemu detektivskemu delu, sem dodal nekaj ukazov za debuggiranje in izpis.", + "", + "Vsi te ukazi za debuggiranje / izpisovanje so v svojih commitih. Končno odkrijem bug, ga popravim in se veselim!", + "", + "Edini problem je, da morem sedaj spraviti moj `bugFix` nazaj v `main` branch. Če uporabim samo fast-forward na `masterju`, potem bi `main` vseboval vse moje debug vrstice, česar si ne želim. Mora obstajati še neka druga pot ..." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Gitu moramo povedati naj skopira čez samo en commit. To je podobno stopnjam prej, ko smo premikali delo okoli -- uporabimo lahko iste ukaze:", + "", + "* `git rebase -i`", + "* `git cherry-pick`", + "", + "da dosežemo ta cilj." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Tebi prepuščam, da se odločiš, kateri ukaz boš uporabil, da končaš stopnjo. Poskrbi samo, da `main` dobi commit na katerega kaže `bugFix` referenca." ] } } diff --git a/src/levels/mixed/jugglingCommits.js b/src/levels/mixed/jugglingCommits.js index b7268699..e1286f80 100644 --- a/src/levels/mixed/jugglingCommits.js +++ b/src/levels/mixed/jugglingCommits.js @@ -15,33 +15,41 @@ exports.level = { ] }, "goalTreeString": "%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C3%27%27%22%2C%22id%22%3A%22master%22%7D%2C%22newImage%22%3A%7B%22target%22%3A%22C2%22%2C%22id%22%3A%22newImage%22%7D%2C%22caption%22%3A%7B%22target%22%3A%22C3%27%27%22%2C%22id%22%3A%22caption%22%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C3%27%22%7D%2C%22C2%27%22%3A%7B%22parents%22%3A%5B%22C3%27%22%5D%2C%22id%22%3A%22C2%27%22%7D%2C%22C2%27%27%22%3A%7B%22parents%22%3A%5B%22C3%27%22%5D%2C%22id%22%3A%22C2%27%27%22%7D%2C%22C2%27%27%27%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%27%27%27%22%7D%2C%22C3%27%27%22%3A%7B%22parents%22%3A%5B%22C2%27%27%27%22%5D%2C%22id%22%3A%22C3%27%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%7D", - "solutionCommand": "git rebase -i HEAD~2 --solution-ordering C3,C2;git commit --amend;git rebase -i HEAD~2 --solution-ordering C2'',C3';git rebase caption master", + "solutionCommand": "git rebase -i HEAD~2 --solution-ordering C3,C2;git commit --amend;git rebase -i HEAD~2 --solution-ordering C2'',C3';git rebase caption main", "startTree": "{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\"},\"newImage\":{\"target\":\"C2\",\"id\":\"newImage\"},\"caption\":{\"target\":\"C3\",\"id\":\"caption\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C2\"],\"id\":\"C3\"}},\"HEAD\":{\"target\":\"caption\",\"id\":\"HEAD\"}}", "name": { "ko": "커밋들 갖고 놀기", "en_US": "Juggling Commits", "de_DE": "Jonglieren mit Commits", - "fr_FR": "Jongler avec les Commits", + "fr_FR": "Jongler avec les commits", "es_AR": "Haciendo malabares con los commits", + "es_ES": "Haciendo malabares con los commits", "pt_BR": "Malabarismo com commits", + "gl" : "Argallando cos commits", "ja": "コミットをやりくりする", "zh_CN": "提交的技巧 #1", "zh_TW": "commit 的戲法", "ru_RU": "Жонглируем коммитами", - "uk": "Жонглюємо комітами" + "uk": "Жонглюємо комітами", + "vi": "Tung hứng commit", + "sl_SI": "Žongliranje s Commiti" }, "hint": { "en_US": "The first command is git rebase -i HEAD~2", "de_DE": "Der erste Befehl ist git rebase -i HEAD~2", "fr_FR": "La première commande est git rebase -i HEAD~2", "es_AR": "El primer comando es git rebase -i HEAD~2", + "es_ES": "El primer comando es git rebase -i HEAD~2", "pt_BR": "O primeiro comando é git rebase -i HEAD~2", + "gl" : "O primeiro comando é git rebase -i HEAD~2", "ja": "最初に打つコマンドはgit rebase -i HEAD~2", "ko": "첫번째 명령은 git rebase -i HEAD~2 입니다", "zh_CN": "第一个命令是 `git rebase -i HEAD~2`", "zh_TW": "第一個命令是 'git rebase -i HEAD~2'", "ru_RU": "Первой командой должна быть git rebase -i HEAD~2", - "uk": "Перша команда має бути git rebase -i HEAD~2" + "uk": "Перша команда має бути git rebase -i HEAD~2", + "vi": "Lệnh đầu tiên là git rebase -i HEAD~2", + "sl_SI": "Prvi ukaz je git rebase -i HEAD~2." }, "startDialog": { "en_US": { @@ -65,14 +73,14 @@ exports.level = { "We will overcome this difficulty by doing the following:", "", "* We will re-order the commits so the one we want to change is on top with `git rebase -i`", - "* We will `commit --amend` to make the slight modification", + "* We will `git commit --amend` to make the slight modification", "* Then we will re-order the commits back to how they were previously with `git rebase -i`", - "* Finally, we will move master to this updated part of the tree to finish the level (via the method of your choosing)", + "* Finally, we will move main to this updated part of the tree to finish the level (via the method of your choosing)", "", "There are many ways to accomplish this overall goal (I see you eye-ing cherry-pick), and we will see more of them later, but for now let's focus on this technique.", "Lastly, pay attention to the goal state here -- since we move the commits twice, they both get an apostrophe appended. One more apostrophe is added for the commit we amend, which gives us the final form of the tree ", "", - "That being said, I can compare levels now based on structure and relative apostrophe differences. As long as your tree's `master` branch has the same structure and relative apostrophe differences, I'll give full credit" + "That being said, I can compare levels now based on structure and relative apostrophe differences. As long as your tree's `main` branch has the same structure and relative apostrophe differences, I'll give full credit." ] } } @@ -84,9 +92,9 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "## Jongler avec les Commits", + "## Jongler avec les commits", "", - "Voici une autre situation fréquente. Vous avez certains changements (`newImage`) et un autre groupe de changements (`caption`) qui sont reliés, ils sont donc empilés l'un sur l'autre dans votre dépôt Git (i.e. un après l'autre).", + "Voici une autre situation fréquente. Vous avez certains changements (`newImage`) et un autre groupe de changements (`caption`) qui sont reliés, ils sont donc empilés l'un sur l'autre dans votre dépôt Git (i.e. l'un après l'autre).", "", "Là où ça se complique c'est lorsque vous devez faire une petite modification dans un commit antérieur. Dans ce cas, les configurations de `newImage` devront changer un peu, même si ce commit est loin dans notre historique !!" ] @@ -99,15 +107,15 @@ exports.level = { "Nous allons régler le problème en faisant ceci :", "", "* Nous allons réordonner les commits pour que celui que nous voulions changer soit sur le dessus `git rebase -i`", - "* Nous allons utiliser `commit --amend` pour faire les petites modifications", + "* Nous allons utiliser `git commit --amend` pour faire les petites modifications", "* Nous allons réordonner les commits dans l'ordre original avec `git rebase -i`", - "* Finalement, nous allons déplacer master vers la nouvelle tête de l'arbre (avec la méthode de votre choix)", + "* Finalement, nous allons déplacer main vers la nouvelle tête de l'arbre (avec la méthode de votre choix)", "", "Il y a plusieurs façons d'atteindre ce but (cherry-pick semble très tentant), mais nous allons parler de cherry-pick plus tard, pour le moment concentrez-vous sur cette technique.", "", - "Pour terminer, Faites attention au but -- Dû au fait que nous déplaçons les commits 2 fois, ils se retrouvent les deux avec une apostrophe. Une deuxième apostrophe est ajouté sur le commit que nous modifions, ce qui nous donne l'arbre finale ", + "Pour terminer, Faites attention au but -- Dû au fait que nous déplaçons les commits 2 fois, ils se retrouvent tous les deux avec une apostrophe. Une deuxième apostrophe est ajoutée sur le commit que nous modifions, ce qui nous donne la forme finale de l'arbre.", "", - "Ceci étant dit, je peux comparer le résultat avec la stucture et les différentes apostophes. Tant que votre arbre master a la même structure et apostrophe le niveau sera considéré réussi." + "Ceci étant dit, je peux comparer le résultat avec la structure et les différentes apostrophes. Tant que votre arbre `main` a la même structure et les différentes apostrophes le niveau sera considéré réussi." ] } }, @@ -121,7 +129,7 @@ exports.level = { "markdowns": [ "## Haciendo malabares con los commits", "", - "Estaes otra situación algo común. Tenés algunos cambios (`newImage`) y otro conjunto de cambios (`caption`) que están relacionados, entonces están apilados en tu repositorio uno encima del otro (es decir, uno después del otro).", + "Esta es otra situación algo común. Tenés algunos cambios (`newImage`) y otro conjunto de cambios (`caption`) que están relacionados, entonces están apilados en tu repositorio uno encima del otro (es decir, uno después del otro).", "", "El tema es que a veces tenés que hacer una pequeña modificación a un commit previo. En este caso, la gente de diseño requiere que cambiemos ligeramente las dimensiones de `newImage`, ¡incluso aunque ese commit ya esté atrás en nuestra historia!" ] @@ -134,15 +142,50 @@ exports.level = { "Superaremos esta dificultad haciendo lo siguiente:", "", "* Vamos a reordenar los commits para que el que queremos cambiar quede arriba de todo con `git rebase -i`", - "* Vamos a hacer `commit --amend` para aplicar la ligera modificación", + "* Vamos a hacer `git commit --amend` para aplicar la ligera modificación", "* Después vamos a reordenar los commits a como estaban con `git rebase -i`", - "* Finalmente, vamos a mover master a esta parte actualizada de nuestor árbol de commits para terminar el nivel (usando el método que prefieras)", + "* Finalmente, vamos a mover main a esta parte actualizada de nuestro árbol de commits para terminar el nivel (usando el método que prefieras)", "", "Hay varias maneras de lograr este objetivo en general (ya te veo haciéndole ojitos al cherry-pick), y veremos algunos más después, pero por ahora concentrémonos en esta técnica.", "", "Por último, prestá atención al estado final acá -- como movemos los commits dos veces, ambos quedan con un apóstrofe. El commit que corregimos tiene un apóstrofe extra, y así nos queda nuestro árbol final", "", - "Habiendo dicho eso, puedo comparar los niveles basándome ahora en la estructura y las diferencias relativas de apóstrofes. Mientras que tu rama `master` tenga la misma estructura y diferencias relativas de apóstrofes, te voy a dar el puntaje completo" + "Habiendo dicho eso, puedo comparar los niveles basándome ahora en la estructura y las diferencias relativas de apóstrofes. Mientras que tu rama `main` tenga la misma estructura y diferencias relativas de apóstrofes, te voy a dar el puntaje completo." + ] + } + }, + ] + }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Haciendo malabares con los commits", + "", + "Esta es otra situación algo común. Tienes algunos cambios (`newImage`) y otro conjunto de cambios (`caption`) que están relacionados, entonces están apilados en tu repositorio uno encima del otro (es decir, uno después del otro).", + "", + "El tema es que a veces tienes que hacer una pequeña modificación a un commit previo. En este caso, la gente de diseño requiere que cambiemos ligeramente las dimensiones de `newImage`, ¡incluso aunque ese commit ya se encuentre atrás en nuestra historia!" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Superaremos esta dificultad haciendo lo siguiente:", + "", + "* Vamos a reordenar los commits para que el que queremos cambiar quede arriba de los demás con `git rebase -i`", + "* Vamos a hacer `git commit --amend` para aplicar la ligera modificación", + "* Después vamos a reordenar los commits a como estaban con `git rebase -i`", + "* Finalmente, vamos a mover main a esta parte actualizada de nuestro árbol de commits para terminar el nivel (usando el método que prefieras)", + "", + "Hay varias maneras de lograr este objetivo en general (ya te veo haciéndole ojitos al cherry-pick), y veremos algunos más después, pero por ahora concentrémonos en esta técnica.", + "", + "Por último, presta atención al estado final -- como movemos los commits dos veces, ambos quedan con un apóstrofe. El commit que corregimos tiene un apóstrofe extra, y así nos queda nuestro árbol final", + "", + "Habiendo dicho eso, puedo comparar los niveles basándome ahora en la estructura y las diferencias relativas de apóstrofes. Mientras que tu rama `main` tenga la misma estructura y diferencias relativas de apóstrofes, te voy a dar el puntaje completo." ] } }, @@ -171,13 +214,48 @@ exports.level = { "* Reordenaremos os commits de forma que aquele que desejamos esteja no topo, com `git rebase -i`", "* Usaremos o comando `git commit --amend` para fazer uma pequena modificação", "* Vamos, então, reordenar os commits na mesma ordem que estavam anteriormente com `git rebase -i`", - "* Finalmente, moveremos o master para essa parte atualizada da árvore para finalizar o nível (usando o método de sua escolha)", + "* Finalmente, moveremos o main para essa parte atualizada da árvore para finalizar o nível (usando o método de sua escolha)", "", "Há muitas formas de alcançar o objetivo final (eu vejo o cherry-pick passando pela sua mente), e veremos mais delas depois, mas por enquanto foquemos nesta técnica.", "", "Por último, preste atenção no estado do \"objetivo\" aqui -- como nós movemos os commits duas vezes, ambos ficam com um apóstrofo. Um apóstrofo adicional é colocado no commit que sofreu o \"amend\", o que nos dá a forma final da árvore ", "", - "Tendo dito isto, posso avaliar a resposta baseado na estrutura e nas diferenças relativas de número de apóstrofos. Desde que o ramo `master` da sua árvore tenha a mesma estrutura, e o número de apóstrofos seja igual a menos de uma constante, darei a você todos os pontos para esta tarefa" + "Tendo dito isto, posso avaliar a resposta baseado na estrutura e nas diferenças relativas de número de apóstrofos. Desde que o ramo `main` da sua árvore tenha a mesma estrutura, e o número de apóstrofos seja igual a menos de uma constante, darei a você todos os pontos para esta tarefa." + ] + } + }, + ] + }, + "gl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Argallando cos commits", + "", + "Aquí está outra situación que acontece con bastante frecuencia. Estás facendo algúns cambios (`newImage`), separado do resto de cambios (`caption`) que están relacionados, deste xeito están apilados un enriba do outro no teu repositorio.", + "", + "O complicado é que ás veces, poida que precises facer unha pequena nota nun commit máis antigo. Neste caso, a persoa de deseño quere mudar un pouco as dimensións da imaxe introducida en `newImage`, a pesar de que ese commit está máis abaixo no noso histórico!!" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Superamos este problema facendo o seguinte:", + "", + "* Reordenaremos os commits seleccionando aqueles que desexamos que estén no cambio, con `git rebase -i`", + "* Empregaremos o comando `git commit --amend` para facer unha pequena modificación", + "* Imos, entón, reordear os commits na mesma orde na que estaban anteriormente con `git rebase -i`", + "* Finalmente, moveremos o main para esa parte atualizada da árbore e así finalizar o nivel (usando o método que máis che pete)", + "", + "Hai moitas formas de obter o obxectivo final (eu vexo o cherry-pick pasando pola túa cachola), e verémolo máis adiante, pero agora ímonos centrar nesta técnica.", + "", + "Por último, preste atención no estado do \"objectivo\" aquí -- como movemos os commits dúas veces, ambos teñen o apóstrofo sumado. O apóstrofo engádese polo commit que nos correximos (amend), o cal danos a forma final da árbore.", + "", + "Contado todo esto, a resposta valídase baseándose na estructura e nos diferentes apóstrofes. Cando a rama `main` teña a mesma estructura, e o número de apóstrofos sexa igual, obterás todos os puntos da tarefa." ] } }, @@ -203,16 +281,16 @@ exports.level = { "markdowns": [ "Um das zu schaffen gehen wir wie folgt vor:", "", - "* Wir sortieren die Commits mit `git rebase -i` so um, dass der, den wir ändern wollen, ganz oben liegt.", + "* Wir sortieren die Commits mit `git rebase -i` so um, dass der Commit, den wir ändern wollen, ganz oben liegt.", "* Wir verändern den Commit mit `git commit --amend`.", - "* Dann sortieren wir die Commit mit einem erneuten `git rebase -i` wieder in die alte Reihenfolge.", - "* Schließlich aktualisieren wir den `master` auf das Ende unseres fertigen Baums, um diesen Level abzuschließen.", + "* Dann sortieren wir die Commits mit einem erneuten `git rebase -i` wieder in die alte Reihenfolge.", + "* Schließlich aktualisieren wir den `main` auf das Ende unseres fertigen Baums, um diesen Level abzuschließen.", "", "Es gibt sehr viele Wege um das Endziel dieses Levels zu erreichen (ich sehe, du schielst auf `cherry-pick`) und wir werden uns später noch andere ansehen. Aber für's erste lass uns diese Methode ausprobieren.", "", - "Beachte den geschilderten Zielzustand. Da wir die Commits zweimal umsortieren bekommen sie jedesmal ein Apostroph hinzugefügt (weil sie jedesmal kopiert werden). Ein weiteres Apostroph entsteht durch den `commit --amend`.", + "Beachte den geschilderten Zielzustand. Da wir die Commits zweimal umsortieren, bekommen sie jedes Mal ein Apostroph hinzugefügt (weil sie jedes Mal kopiert werden). Ein weiteres Apostroph entsteht durch den `git commit --amend`.", "", - "Zuguterletzt noch eine Bemerkung: ich kann Level nur auf Struktur und Apostroph-Differenz prüfen. So lange wie dein `master` am Ende dieselbe Struktur und Apostroph-Differenz aufweist wie der Ziel-`master`, ist der Level bestanden." + "Zuguterletzt noch eine Bemerkung: ich kann Level nur auf Struktur und Apostroph-Differenz prüfen. So lange wie dein `main` am Ende dieselbe Struktur und Apostroph-Differenz aufweist wie der Ziel-`main`, ist der Level bestanden." ] } }, @@ -239,7 +317,7 @@ exports.level = { "この困難な状況を、以下の手順で克服することを考えます:", "", "* `git rebase -i`を使って順番を変更する。これで、変更をかけたいコミットを一番先頭に持ってくる。", - "* `commit --amend`コマンドで僅かな変更を行う", + "* `git commit --amend`コマンドで僅かな変更を行う", "* `git rebase -i`コマンドを再度使って、先頭に持ってきていたコミットを元に戻す", "* 最後に、レベルクリアのためにmasterブランチを先頭に持ってくる", "", @@ -272,14 +350,14 @@ exports.level = { "我们可以通过下面的方法来克服困难:", "", "* 先用 `git rebase -i` 将提交重新排序,然后把我们想要修改的提交记录挪到最前", - "* 然后用 `commit --amend` 来进行一些小修改", + "* 然后用 `git commit --amend` 来进行一些小修改", "* 接着再用 `git rebase -i` 来将他们调回原来的顺序", - "* 最后我们把 master 移到修改的最前端(用你自己喜欢的方法),就大功告成啦!", + "* 最后我们把 main 移到修改的最前端(用你自己喜欢的方法),就大功告成啦!", "", "当然完成这个任务的方法不止上面提到的一种(我知道你在看 cherry-pick 啦),之后我们会多点关注这些技巧啦,但现在暂时只专注上面这种方法。", "最后有必要说明一下目标状态中的那几个`'` —— 我们把这个提交移动了两次,每移动一次会产生一个 `'`;而 C2 上多出来的那个是我们在使用了 amend 参数提交时产生的,所以最终结果就是这样了。", "", - "也就是说,我在对比结果的时候只会对比提交树的结构,对于 `'` 的数量上的不同,并不纳入对比范围内。只要你的 `master` 分支结构与目标结构相同,我就算你通过。" + "也就是说,我在对比结果的时候只会对比提交树的结构,对于 `'` 的数量上的不同,并不纳入对比范围内。只要你的 `main` 分支结构与目标结构相同,我就算你通过。" ] } } @@ -306,9 +384,9 @@ exports.level = { "為了克服這個困難,我們可以按照下面的方法來做:", "", "* 先用 `git rebase -i` 將 commit 重新排序,然後把我們想要修改的 commit 移到最前面", - "* 然後用 `commit --amend` 來進行一些修改", + "* 然後用 `git commit --amend` 來進行一些修改", "* 接著再用 `git rebase -i` 來將他們按照最開始的順序重新排好", - "* 最後我們把 master 移到這個修改的最前端(用你自己喜歡的方法),就大功告成啦!", + "* 最後我們把 main 移到這個修改的最前端(用你自己喜歡的方法),就大功告成啦!", "", "當然還有許多方法可以完成這個任務(我知道你在想 cherry-pick 啦),之後我們會多點關注這些技巧啦,但現在暫時只注意上面這種方法。", "", @@ -328,7 +406,7 @@ exports.level = { "", "이번에도 꽤 자주 발생하는 상황입니다. `newImage`와 `caption` 브랜치에 각각의 변경내역이 있고 서로 약간 관련이 있어서, 저장소에 차례로 쌓여있는 상황입니다.", "", - "때로는 이전 커밋의 내용을 살짝 바꿔야하는 골치아픈 상황에 빠지게 됩니다. 이번에는 디자인 쪽에서 우리의 작업이력(history)에서는 이미 한참 전의 커밋 내용에 있는 `newImage`의 크기를 살짝 바꿔달라는 요청이 들어왔습니다." + "때로는 이전 커밋의 내용을 살짝 바꿔야하는 골치아픈 상황에 빠지게 됩니다. 이번에는 디자인 쪽에서 우리의 작업이력(history)에서는 이미 한참 전의 커밋 내용에 있는 `newImage`의 크기를 살짝 바꿔 달라는 요청이 들어왔습니다." ] } }, @@ -339,9 +417,9 @@ exports.level = { "이 문제를 다음과 같이 풀어봅시다:", "", "* `git rebase -i` 명령으로 우리가 바꿀 커밋을 가장 최근 순서로 바꾸어 놓습니다", - "* `commit --amend` 명령으로 커밋 내용을 정정합니다", + "* `git commit --amend` 명령으로 커밋 내용을 정정합니다", "* 다시 `git rebase -i` 명령으로 이 전의 커밋 순서대로 되돌려 놓습니다", - "* 마지막으로, master를 지금 트리가 변경된 부분으로 이동합니다. (편하신 방법으로 하세요)", + "* 마지막으로, main을 지금 트리가 변경된 부분으로 이동합니다. (편하신 방법으로 하세요)", "", "이 목표를 달성하기 위해서는 많은 방법이 있는데요(체리픽을 고민중이시죠?), 체리픽은 나중에 더 살펴보기로 하고, 우선은 위의 방법으로 해결해보세요.", "", @@ -372,13 +450,13 @@ exports.level = { "Преодолеть эти трудности можно следующим образом:", "", "* Переставить коммит так, чтобы нужный находился наверху при помощи `git rebase -i`", - "* Внести изменения при помощи `commit --amend`", + "* Внести изменения при помощи `git commit --amend`", "* Переставить всё обратно при помощи `git rebase -i`", - "* И наконец, переместить master на изменённую часть дерева, чтобы закончить уровень.", + "* И наконец, переместить main на изменённую часть дерева, чтобы закончить уровень.", "", "Это задание можно выполнить несколькими способами (и, гляжу, ты посматриваешь на cherry-picking), но сейчас сосредоточься на вышеописанном методе.", "", - "Обрати внимание на итоговое состояние в этом уровне – так как мы дважды перемещаем коммиты, оба они получат по апострофу. Ещё один апостроф добавляется, когда мы делаем `commit --amend`.", + "Обрати внимание на итоговое состояние в этом уровне – так как мы дважды перемещаем коммиты, оба они получат по апострофу. Ещё один апостроф добавляется, когда мы делаем `git commit --amend`.", "", "Важно, чтобы совпадало не только дерево коммитов, но и количество апострофов." ] @@ -407,14 +485,82 @@ exports.level = { "Ми поборимо цю складність наступним чином:", "", "* Ми відсортуємо коміти таким чином, щоб той, який ми хочемо змінити, був останнім за допомогою `git rebase -i`", - "* Ми виконаємо `commit --amend` щоб внести невелику правку до останнього коміту", + "* Ми виконаємо `git commit --amend` щоб внести невелику правку до останнього коміту", "* Тоді ми відсортуємо коміти в попередньому порядку, за допомогою `git rebase -i`", - "* І на останок, ми пересунемо master на змінену частину дерева щоб закінчити цей рівень(ти можеш вибрати метод)", + "* І на останок, ми пересунемо main на змінену частину дерева щоб закінчити цей рівень(ти можеш вибрати метод)", "", "Насправді є кілька способів як виконати поставлену задачу (Я бачу, ти поглядаєш на cherry-pick), і ми розберемося з ними всіма трохи пізніше, але зараз скористаймося саме цим методом.", "Зверни увагу на фінальний стан в цьому рівні -- позаяк ми перемістили коміти двічі, кожен з них отримає по апострофу. Ще один апостроф додасться коли ми виконаємо commit --amend.", "", - "Враховуючи сказане вище, я буду порівнювати дерево як за назвою коміта, так і за кількістю апострофів. Щойно дерево цілей та master співпадуть, ти пройдеш цей рівень." + "Враховуючи сказане вище, я буду порівнювати дерево як за назвою коміта, так і за кількістю апострофів. Щойно дерево цілей та main співпадуть, ти пройдеш цей рівень." + ] + } + } + ] + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Tung hứng Commit", + "", + "Có một tình huống xảy ra khá thường xuyên. Bạn có vài thay đổi trên (`newImage`) và một vài thay đổi khác trên (`caption`) và chúng lại liên quan đến nhau, nên chúng nằm chồng lên nhau trong kho của bạn (một lại nối một).", + "", + "Tréo ngoe là bạn lại phải điều chỉnh một chút ở commit trước. Giả sử như tay thiết kết muốn ta đổi chiều của `newImage` một chút, mặc dù commit ấy đã xưa lắm rồi!!" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Để khắc phục khó khăn này ta có thể làm như sau:", + "", + "* Ta sẽ dùng `git rebase -i` sắp xếp lại commit để cái ta cần sửa sẽ nằm trên cùng", + "* Ta sẽ dùng `git commit --amend` tạo ra một điều chỉnh nhỏ", + "* Sau đó ta sẽ lại sắp xếp lại commit như trước bằng cách dùng `git rebase -i`", + "* Cuối cùng, ta sẽ chuyển `main` tới phần đã cập nhật để hoàn thành cấp độ (dùng cách nào tùy bạn)", + "", + "Có nhiều cách để hoàn thành mục tiêu (Tôi thấy bạn hấp háy sang cherry-pick rồi đấy), rồi ta sẽ thấy chúng nhiều hơn, nhưng giờ hãy cứ tập trung vào kỹ thuật này đã.", + "Sau cùng thì, để ý các dấu nháy đơn(') chứ?-- vì ta đã chuyển commit 2 lần, nên chúng có thêm một dấu nháy đơn. Và một dấu nữa cho commit mà ta đã sửa đổi, thế là ta có trạng thái cuối cùng của cây lịch sử ", + "", + "Nói cách khác, khi tôi so sánh kết quả, tôi chỉ so sánh cấu trúc của cây lịch sử. Sự khác biệt về số lượng `'` không được bao gồm trong so sánh. Miễn là cấu trúc nhánh `main` của bạn giống với cấu trúc đích, tôi sẽ vẫn để bạn qua bài." + ] + } + } + ] + }, + "sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Žongliranje s Commiti", + "", + "Tu je še ena situacija, ki se dogaja kar pogosto. Imaš nekaj sprememb (`newImage`) in še nekaj drugih sprememb (`caption`), ki so povezane in zložene druga na drugo v tvojem repozitoriju.", + "", + "Včasih se zgodi, da bi rad naredil manjšo spremembo na zgodnejšem commitu. V tem primeru si naš dizajner želi, da spremenimo dimenzije slike `newImage`, čeprav je commit daleč nazaj v naši zgodovini!!" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Ta izziv bomo rešili takole:", + "", + "* Preuredili bomo commite tako, da bo tisti, ki ga želimo spremeniti, na vrhu z `git rebase -i`", + "* Izvedli bomo `git commit --amend`, da naredimo naš popravek", + "* Nato bomo preuredili commite nazaj v začetno stanje z `git rebase -i`", + "* Za konec bomo premaknili main na ta posodobljen del drevesa, da zaključimo stopnjo (z metodo po tvoji izbiri)", + "", + "Obstaja več načinov, da dosežemo ta cilj (vidim te kako gledaš cherry-pick) s katerimi se bomo ukvarjali kasneje, ampak za zdaj se osredotočimo na to tehniko.", + "In nenazadnje, bodi pozoren na ciljno stanje -- ker premaknemo commit dvakrat, oba dobita pripet opuščaj zgoraj. Še eden je dodan za ammendan commit, torej skupno tri.", + "", + "Sedaj lahko primerjam stopnje po strukturi in relativni spremembi opuščajev. Dokler ima `main` branch na tvojem drevesu enako strukturo in število opuščajev, dobiš vse točke." ] } } diff --git a/src/levels/mixed/jugglingCommits2.js b/src/levels/mixed/jugglingCommits2.js index 26fb0a0c..0f20a3da 100644 --- a/src/levels/mixed/jugglingCommits2.js +++ b/src/levels/mixed/jugglingCommits2.js @@ -1,6 +1,6 @@ exports.level = { "goalTreeString": "%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C3%27%22%2C%22id%22%3A%22master%22%7D%2C%22newImage%22%3A%7B%22target%22%3A%22C2%22%2C%22id%22%3A%22newImage%22%7D%2C%22caption%22%3A%7B%22target%22%3A%22C3%22%2C%22id%22%3A%22caption%22%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C2%27%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%27%22%7D%2C%22C2%27%27%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%27%27%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C2%27%27%22%5D%2C%22id%22%3A%22C3%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%7D", - "solutionCommand": "git checkout master;git cherry-pick C2;git commit --amend;git cherry-pick C3", + "solutionCommand": "git checkout main;git cherry-pick C2;git commit --amend;git cherry-pick C3", "disabledMap": { "git revert": true }, @@ -9,7 +9,7 @@ exports.level = { "goalAsserts": { "master": [ function(data) { - return data.C2 > data.C3; + return data.C2 >= data.C3; }, function(data) { return data.C2 > data.C1; @@ -21,26 +21,34 @@ exports.level = { "en_US": "Juggling Commits #2", "fr_FR": "Jongler avec les commits #2", "es_AR": "Haciendo malabares con los commits #2", + "es_ES": "Haciendo malabares con los commits #2", "pt_BR": "Malabarismo com commits #2", + "gl" : "Argallando cos commits #2", "de_DE": "Jonglieren mit Commits Teil 2", "ja": "コミットをやりくりする その2", "zh_CN": "提交的技巧 #2", "zh_TW": "commit 的戲法 #2", "ru_RU": "Жонглируем коммитами №2", - "uk": "Жонглюємо комітами #2" + "uk": "Жонглюємо комітами #2", + "vi": "Tung hứng commit #2", + "sl_SI": "Žongliranje s Commiti #2" }, "hint": { - "en_US": "Don't forget to forward master to the updated changes!", - "fr_FR": "N'oubliez pas de forwarder la branch master dans la nouvelle branch", - "es_AR": "¡No te olvides de avanzar master a los cambios actualizados!", - "pt_BR": "Não se esqueça de avançar a referência do master para as mudanças efetuadas!", - "de_DE": "Vergiss nicht den master auf die aktuelle Version vorzuspulen", + "en_US": "Don't forget to forward main to the updated changes!", + "fr_FR": "N'oubliez pas d'appliquer les changements depuis la branche main", + "es_AR": "¡No te olvides de avanzar main a los cambios actualizados!", + "es_ES": "¡No te olvides de avanzar main a los cambios actualizados!", + "pt_BR": "Não se esqueça de avançar a referência do main para as mudanças efetuadas!", + "gl" : "¡Non te esquezas de avanzar main ós cambios actualizados!", + "de_DE": "Vergiss nicht den main auf die aktuelle Version vorzuspulen", "ja": "masterのポインタを先に進めることを忘れずに!", - "ko": "master를 변경 완료한 커밋으로 이동(forward)시키는 것을 잊지 마세요!", - "zh_CN": "别忘记了将 master 快进到最新的更新上!", - "zh_TW": "別忘記了將 master 推到最新的 commit 上面!", - "ru_RU": "Не забудь переместить master на последние изменения.", - "uk": "Не забудь перемістити master на останні зміни!" + "ko": "main을 변경 완료한 커밋으로 이동(forward)시키는 것을 잊지 마세요!", + "zh_CN": "别忘记了将 main 快进到最新的更新上!", + "zh_TW": "別忘記了將 main 推到最新的 commit 上面!", + "ru_RU": "Не забудь переместить main на последние изменения.", + "uk": "Не забудь перемістити main на останні зміни!", + "vi": "Đừng quên đẩy nhánh main lên cập nhật mới nhất!", + "sl_SI": "Ne pozabi prestaviti main naprej na posodobljene spremembe." }, "startDialog": { "en_US": { @@ -55,7 +63,7 @@ exports.level = { "", "As you saw in the last level, we used `rebase -i` to reorder the commits. Once the commit we wanted to change was on top, we could easily --amend it and re-order back to our preferred order.", "", - "The only issue here is that there is a lot of reordering going on, which can introduce rebase conflicts. Let's look at another method with `git cherry-pick`" + "The only issue here is that there is a lot of reordering going on, which can introduce rebase conflicts. Let's look at another method with `git cherry-pick`." ] } }, @@ -68,10 +76,10 @@ exports.level = { "Here's a small refresher demo:" ], "afterMarkdowns": [ - "Nice! Let's move on" + "Nice! Let's move on." ], "command": "git cherry-pick C2", - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit" + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" } }, { @@ -80,7 +88,7 @@ exports.level = { "markdowns": [ "So in this level, let's accomplish the same objective of amending `C2` once but avoid using `rebase -i`. I'll leave it up to you to figure it out! :D", "", - "Remember, the exact number of apostrophe's (') on the commit are not important, only the relative differences. For example, I will give credit to a tree that matches the goal tree but has one extra apostrophe everywhere" + "Remember, the exact number of apostrophe's (') on the commit are not important, only the relative differences. For example, I will give credit to a tree that matches the goal tree but has one extra apostrophe everywhere." ] } } @@ -98,7 +106,7 @@ exports.level = { "", "Comme vu dans le niveau précédent, nous utilisons `rebase -i` pour réordonner les commits. Une fois que le commit à modifier est celui à la tête, nous pouvons facilement faire un --amend et réordonner dans l'ordre voulu.", "", - "La difficulté ici est qu'il y a beaucoup de changements, ce qui peut introduire des conflits de rebase. Essayons avec l'autre méthode `git cherry-pick`" + "La difficulté ici est qu'il y a beaucoup de changements, ce qui peut introduire des conflits de rebase. Essayons avec l'autre méthode `git cherry-pick`." ] } }, @@ -114,7 +122,7 @@ exports.level = { "Bien ! continuons." ], "command": "git cherry-pick C2", - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit" + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" } }, { @@ -141,7 +149,7 @@ exports.level = { "", "Como viste en el último nivel, usamos `rebase -i` para reordenar los commits. Una vez que el commit que queríamos cambiar estaba arriba de todo, pudimos `--amend`earlo fácilmente y reordenarlo a como queríamos.", "", - "El único problema con esto es que hay mucho reordenamiento, que puede generar conflictos al rebasear. Veamos otro método usando `git cherry-pick`" + "El único problema con esto es que hay mucho reordenamiento, que puede generar conflictos al rebasear. Veamos otro método usando `git cherry-pick`." ] } }, @@ -157,7 +165,7 @@ exports.level = { "¡Bien! Sigamos..." ], "command": "git cherry-pick C2", - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit" + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" } }, { @@ -166,7 +174,50 @@ exports.level = { "markdowns": [ "Entonces, en este nivel vamos a lograr el mismo objetivo de corregir `C2`, pero sin usar `rebase -i`. Te dejo a vos el darte cuenta cómo :D", "", - "Acordate, la cantidad exacta de apóstrofes (') en el commit no es importante, sólo la diferencia relativa. Por ejemplo, le voy a dar puntaje a un árbol que matchee el objetivo pero cuyos commits tengan todos un apóstrofe extra" + "Acordate, la cantidad exacta de apóstrofes (') en el commit no es importante, sólo la diferencia relativa. Por ejemplo, le voy a dar puntaje a un árbol que matchee el objetivo pero cuyos commits tengan todos un apóstrofe extra." + ] + } + } + ] + }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Haciendo malabares con los commits #2", + "", + "*Si no completaste Haciendo malabares con los commits #1 (el nivel anterior), hazlo antes de continuar*", + "", + "Como viste en el último nivel, usamos `rebase -i` para reordenar los commits. Una vez que el commit que queríamos cambiar se encontraba arriba de todo, pudimos `--amend`earlo fácilmente y reordenarlo a como queríamos.", + "", + "El único problema con esto es que hay mucho reordenamiento, que puede generar conflictos al rebasear. Veamos otro método usando `git cherry-pick`." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Recuerda que git cherry-pick va a traer un commit de cualquier parte del árbol sobre HEAD (siempre que ese otro commit no sea un ancestro de HEAD).", + "", + "Una pequeña demo para refrescar la idea:" + ], + "afterMarkdowns": [ + "¡Bien! Sigamos..." + ], + "command": "git cherry-pick C2", + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Entonces, en este nivel vamos a lograr el mismo objetivo de corregir `C2`, pero sin usar `rebase -i`. Te dejo a ti el darte cuenta cómo :D", + "", + "Recuerda, la cantidad exacta de apóstrofes (') en el commit no es importante, sólo la diferencia relativa. Por ejemplo, le voy a dar una puntuación a un árbol que coincida con el objetivo pero cuyos commits tengan todos un apóstrofe extra." ] } } @@ -184,7 +235,7 @@ exports.level = { "", "Como você viu no nível anterior, usamos `rebase -i` para reordenar os commits. Uma vez que o commit que queríamos mudar estava no topo, pudemos facilmente usar o `--amend` e depois reordená-lo de volta para obter nossa ordem preferida.", "", - "O único problema aqui é que há muita reordenação ocorrendo, o que pode introduzir conflitos de rebase. Vamos dar uma olhada em outro método, usando o `git cherry-pick`" + "O único problema aqui é que há muita reordenação ocorrendo, o que pode introduzir conflitos de rebase. Vamos dar uma olhada em outro método, usando o `git cherry-pick`." ] } }, @@ -197,10 +248,10 @@ exports.level = { "Aqui está uma demonstração para refrescar sua memória:" ], "afterMarkdowns": [ - "Ótimo! Vamos em frente" + "Ótimo! Vamos em frente." ], "command": "git cherry-pick C2", - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit" + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" } }, { @@ -209,7 +260,50 @@ exports.level = { "markdowns": [ "Então, neste nível, vamos alcançar o mesmo objetivo de fazer \"amend\" no `C2`, mas evitaremos usar o `rebase -i`. Agora vou deixar com você a tarefa de descobrir como fazer! :D", "", - "Lembre-se, o número exato de apóstrofos (') nos commits não é importante, apenas as diferenças relativas. Por exemplo, darei todos os pontos nesta tarefa se você obtiver o mesmo resultado da árvore da visualização de objetivo com um apóstrofo extra em todos os commits" + "Lembre-se, o número exato de apóstrofos (') nos commits não é importante, apenas as diferenças relativas. Por exemplo, darei todos os pontos nesta tarefa se você obtiver o mesmo resultado da árvore da visualização de objetivo com um apóstrofo extra em todos os commits." + ] + } + } + ] + }, + "gl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Argallando cos commits #2", + "", + "*No caso de non ter rematado o tema anterior (Argallando cos commits #1), por favor faino antes de continuar*.", + "", + "Como puideches ver no anterior tema, usamos `rebase -i` para reordear os commits. Unha vez que atopamos o commit que queriamos modificar, puidemos empregar sinxelamente o `--amend`, e depois reordenalo de volta para obter a nosa orde preferida.", + "", + "O único problema aquí é que hai moita reordenación ocorrendo, o que pode introducir conflitos no rebase. Imos votar unha ollada a outro método, o uso de `git cherry-pick`." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Lembra que `git cherry-pick` copiará un commit de qualquera lugar na árbore enriba do HEAD (sempre e cando non sexa ancestro do HEAD).", + "", + "Aquí está unha demostración para que refresques a memoria:" + ], + "afterMarkdowns": [ + "¡A tope! Seguimos." + ], + "command": "git cherry-pick C2", + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Entón, neste nivel, imos completar o mesmo obxectivo que facendo \"amend\" no `C2`, pero evitando facer o `rebase -i`. Agora deixámoste que lle des os miolos para sacar o exercicio! :D", + "", + "Recorda, o número exacto de apóstrofos (') nos commits non é importante, só as diferencias relativas. Por exemplo, levarás todos os puntos desta tarefa se obtés o mesmo resultado da árbore que se mostra na visualización do exercicio con un apóstrofo extra en tódolos commits." ] } } @@ -225,7 +319,7 @@ exports.level = { "", "Du solltest \"Jonglieren mit Commits\" (den vorherigen Level) bestanden haben, bevor du dich an diesem hier versuchst.", "", - "Wie du im letzten Level gesehen hast haben wir `git rebase -i` genutzt, um die Commits neu anzuordnen. Sobald der Commit, den wir ändern wollte, ganz oben war, konnten wir das auch einfach mit `git commit --amend` tun. Danach haben wir die alte Reihenfolge wiederhergestellt.", + "Wie du im letzten Level gesehen hast, haben wir `git rebase -i` genutzt, um die Commits neu anzuordnen. Sobald der Commit, den wir ändern wollten, ganz oben war, konnten wir ihn einfach mit `git commit --amend` anpassen. Danach haben wir die alte Reihenfolge wiederhergestellt.", "", "Das einzige Problem ist hier, dass da eine Menge Umsortieren stattfindet, was zu Rebase-Konflikten führen kann. Schauen wir uns also eine Methode mit `git cherry-pick` an." ] @@ -235,7 +329,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Wie du dich erinnerst macht `git cherry-pick` eine Kopie des angegebenen Commits und fügt sie an `HEAD` an (es sei denn der Commit ist ein Vorgänger von `HEAD`).", + "Wie du dich erinnerst, macht `git cherry-pick` eine Kopie des angegebenen Commits und fügt sie an `HEAD` an (es sei denn der Commit ist ein Vorgänger von `HEAD`).", "", "Hier eine kleine Demo zur Erinnerung:" ], @@ -243,7 +337,7 @@ exports.level = { "Schick! Und weiter geht's." ], "command": "git cherry-pick C2", - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit" + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" } }, { @@ -286,7 +380,7 @@ exports.level = { "できました!次へ進みましょう" ], "command": "git cherry-pick C2", - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit" + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" } }, { @@ -307,7 +401,7 @@ exports.level = { "markdowns": [ "## 提交的技巧 #2", "", - "*如果你还没有完成“提交的技巧 #1”(前一关)的话,请选通过以后再来!*", + "*如果你还没有完成“提交的技巧 #1”(前一关)的话,请先通过以后再来!*", "", "正如你在上一关所见到的,我们可以使用 `rebase -i` 对提交记录进行重新排序。只要把我们想要的提交记录挪到最前端,我们就可以很轻松的用 `--amend` 修改它,然后把它们重新排成我们想要的顺序。", "", @@ -327,7 +421,7 @@ exports.level = { "afterMarkdowns": [ "看到了吧?我们继续" ], - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit" + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" } }, { @@ -370,7 +464,7 @@ exports.level = { "afterMarkdowns": [ "太棒了,我們繼續吧!" ], - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit" + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" } }, { @@ -411,7 +505,7 @@ exports.level = { "좋아요! 계속할게요" ], "command": "git cherry-pick C2", - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit" + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" } }, { @@ -452,7 +546,7 @@ exports.level = { "Ок! Едем дальше!" ], "command": "git cherry-pick C2", - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit" + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" } }, { @@ -479,7 +573,7 @@ exports.level = { "", "Як ти бачив в попередньому рівні, ми використали `rebase -i` щоб впорядкувати набір комітів. Як тільки потрібний коміт опиняється вгорі, його досить легко змінити за допомогою --amend й потім відсортувати коміти в попередньому порядку.", "", - "Єдина проблема з таким підходом полягає в тому, що виконується досить багато перестановок комітів, що може призвести до конфліктів при виконанні rebase. Спробуймо інший підхід який використовує `git cherry-pick`" + "Єдина проблема з таким підходом полягає в тому, що виконується досить багато перестановок комітів, що може призвести до конфліктів при виконанні rebase. Спробуймо інший підхід який використовує `git cherry-pick`." ] } }, @@ -495,7 +589,7 @@ exports.level = { "Добре! Продовжуємо" ], "command": "git cherry-pick C2", - "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit" + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" } }, { @@ -509,6 +603,92 @@ exports.level = { } } ] + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Tung hứng Commit #2", + "", + "*Nếu bạn vẫn chưa hoàn thành Tung hứng Commit #1 (cấp độ trước), hãy làm nó trước khi tiếp tục*", + "", + "Như bạn đã thấy ở cấp độ trước, ta dùng `rebase -i` để sắp xếp lại các commit. Một khi commit mà ta muốn sửa đã ở trên cùng, ta có thể dễ dàng --chỉnh sửa(amend) nó và sau đó sắp xếp lại trật tự lúc trước.", + "", + "Nhưng mà vẫn tồn tại vấn đề khi mà ta sắp xếp quá nhiều, điều này có thể dẫn đến xung đột khi rebase. Thử dùng cách khác với `git cherry-pick` nào" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Hãy nhớ rằng cherry-pick sẽ thả commit ở bất cứ đâu xuống dưới HEAD (miễn là nó không phải cha ông hay tổ tiên gì của HEAD).", + "", + "Hãy xem thử minh họa nhỏ sau:" + ], + "afterMarkdowns": [ + "Hay! Tiếp tục nào" + ], + "command": "git cherry-pick C2", + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Vậy thì ở cấp độ này, hãy làm hoàn thành mục tiêu tương tự là chỉnh sửa `C2` một lần nhưng hãy tránh dùng `rebase -i`. Tự tìm cách đi nhé! :D", + "", + "Nhớ rằng, số lượng dấu nháy dơn (') trên commit không quan trọng, quan trọng là mối tương liên các tham chiếu. Nói cách khác, kể cả bất cứ commit nào của bạn có thêm một đấu(') tôi vẫn công nhận đáp án của bạn" + ] + } + } + ] + }, + "sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Žongliranje s Commiti #2", + "", + "Če še nisi končal Žongliranje s Commiti #1 (prejšnjo stopnjo), jo končaj pred nadaljevanjem", + "", + "Kot si videl v prejšnji stopnji, smo uporabili `rebase -i` za preureditev commitov. Ko je bil commit, ki smo ga želeli spremeniti, na vrhu, smo preprosto uporabili --amend in preuredili nazaj v naše željeno stanje.", + "", + "Edini problem tu je, da je veliko prerazporejanja, kar lahko povzroči rebase konflikte. Poglejmo si še eno drugo tehniko imenovano `git cherry-pick`." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Git cherry-pick bo skopiral commit iz bilokaterega mesta na drevesu na HEAD (seveda dokler ni ta commit že prednik HEAD).", + "", + "Tu je mali osvežitveni primer:" + ], + "afterMarkdowns": [ + "Odlično! Nadaljujmo ..." + ], + "command": "git cherry-pick C2", + "beforeCommand": "git checkout -b bugFix; git commit; git checkout main; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Torej v tej stopnji bi radi enako spremenili `C2`, ampak tokrat brez uporabe `rebase -i`. Kako to narediti, prepustim tebi! :D", + "", + "Točno število opuščajev (') na commitu ni pomembno, pomembna je samo relativna sprememba. Naprimer, vse točko bom dal tudi za drevo, ki ustreza ciljenmu drevesu, a ima povsod dodaten opuščaj." + ] + } + } + ] } } }; diff --git a/src/levels/mixed/tags.js b/src/levels/mixed/tags.js index 69285b00..9415642f 100644 --- a/src/levels/mixed/tags.js +++ b/src/levels/mixed/tags.js @@ -1,19 +1,23 @@ -exports.level = { +exports.level = { "goalTreeString": "{\"branches\":{\"master\":{\"target\":\"C5\",\"id\":\"master\",\"remoteTrackingBranchID\":null},\"side\":{\"target\":\"C3\",\"id\":\"side\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C2\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C1\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C2\",\"C4\"],\"id\":\"C5\"}},\"tags\":{\"v1\":{\"target\":\"C2\",\"id\":\"v1\",\"type\":\"tag\"},\"v0\":{\"target\":\"C1\",\"id\":\"v0\",\"type\":\"tag\"}},\"HEAD\":{\"target\":\"C2\",\"id\":\"HEAD\"}}", - "solutionCommand": "git tag v1 side~1;git tag v0 master~2;git checkout v1", + "solutionCommand": "git tag v1 side~1;git tag v0 main~2;git checkout v1", "startTree": "{\"branches\":{\"master\":{\"target\":\"C5\",\"id\":\"master\",\"remoteTrackingBranchID\":null},\"side\":{\"target\":\"C3\",\"id\":\"side\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C2\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C1\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C2\",\"C4\"],\"id\":\"C5\"}},\"tags\":{},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}", "name": { "en_US": "Git Tags", "de_DE": "Git Tags", "ja" : "Gitのタグ", "es_AR": "Tags en git", + "es_ES": "Tags en git", "pt_BR": "Tags no Git", + "gl" : "Etiquetas en git", "fr_FR": "Git Tags", "zh_CN": "Git Tag", "zh_TW": "git tag", "ru_RU": "git tag", "ko" : "Git 태그", - "uk" : "Git Tags" + "uk" : "Git Tags", + "vi" : "Tag trong Git", + "sl_SI": "Git Tagi" }, "hint": { "en_US": "you can either check out the commit directly or simply checkout the tag!", @@ -21,12 +25,16 @@ "de_DE": "Du kannst den Checkout entweder direkt auf den Commit oder das Tag machen.", "ja" : "コミットを直接チェックアウトできますが、簡単にタグでチェックアウトすることも可能!", "es_AR": "Podés checkoutear directamente el commit, ¡o simplemente el tag!", + "es_ES": "Puedes hacer checkout directamente el commit, ¡o simplemente el tag!", "pt_BR": "Você pode fazer checkout diretamente no commit ou na tag correspondente!", + "gl" : "Podes saltar directamente ó commit, ¡ou a etiqueta, que é máis doado!", "zh_TW": "你可以直接 checkout 到 commit 上,或是簡單的 checkout 到 tag 上", "zh_CN": "你可以直接 checkout 到 commit 上,或是简单地 checkout 到 tag 上", "ru_RU": "Можно сделать checkout напрямую на коммит или же на тег", "ko" : "커밋을 직접 또는 태그를 이용해서 체크아웃할수 있습니다!", - "uk" : "ти можеш або зробити checkout коміта напряму чи просто зачекаутити таг!" + "uk" : "ти можеш або зробити checkout коміта напряму чи просто зачекаутити таг!", + "vi" : "Bạn có thể chuyển trực tiếp sang commit hoặc đơn giản là chuyển sang tag!", + "sl_SI": "Checkoutaš lahko neposredno commit ali pa preprosto njegov tag!" }, "startDialog": { "en_US": { @@ -60,10 +68,10 @@ "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Let's try making a tag at `C1` which is our version 1 prototype" + "Let's try making a tag at `C1` which is our version 1 prototype." ], "afterMarkdowns": [ - "There! Quite easy. We named the tag `v1` and referenced the commit `C1` explicitly. If you leave the commit off, git will just use whatever `HEAD` is at" + "There! Quite easy. We named the tag `v1` and referenced the commit `C1` explicitly. If you leave the commit off, git will just use whatever `HEAD` is at." ], "command": "git tag v1 C1", "beforeCommand": "git commit" @@ -100,7 +108,7 @@ "type": "ModalAlert", "options": { "markdowns": [ - "Vous l'avez deviné ! Git tags offre cette fonctionnalité : les tags marquent à jamais certains commits comme \"milestone\" auxquels vous pouvez vous référez comme à des branches.", + "Vous l'avez deviné ! Les tags Git offrent cette fonctionnalité : les tags marquent à jamais certains commits comme \"milestone\" (étape clé) auxquels vous pouvez vous référer comme à des branches.", "", "Encore plus important, il sont définitifs. Vous ne pouvez donc pas rajouter de commit dans un tag : les tags sont un peu comme un pointeur définitif dans l'arbre des commits.", "", @@ -112,7 +120,7 @@ "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Essayons de faire un tag sur C1 (qui représente la version 1 de notre prototype)" + "Essayons de faire un tag sur C1 (qui représente la version 1 de notre prototype)." ], "afterMarkdowns": [ "Voila, facile non ? Nous nommons le tag `v1` et il pointe vers le commit `C1`. Si vous ne spécifiez pas le commit, le tag pointera là où se trouve `HEAD`." @@ -271,7 +279,7 @@ "Creemos un tag en `C1`, que es nuestro prototipo de la versión 1" ], "afterMarkdowns": [ - "¡Ahí está! Bastante simple. Nombramos al tag `v1` y referenciamos explícitamente al commit `C1`. Si no especificás el commit, git va a usar al apuntado por `HEAD`" + "¡Ahí está! Bastante simple. Nombramos al tag `v1` y referenciamos explícitamente al commit `C1`. Si no especificás el commit, git va a usar al apuntado por `HEAD`." ], "command": "git tag v1 C1", "beforeCommand": "git commit" @@ -289,6 +297,58 @@ } ] }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Tags en git", + "", + "Como aprendiste en lecciones anteriores, las ramas pueden moverse fácilmente, y en general van referenciando distintos commits a medida que el trabajo se va completando en ellas. Las ramas cambian fácilmente, suelen ser temporales, y siempre cambiantes.", + "", + "Si ese es el caso, te podrías estar preguntando si hay una manera de marcar *permanentemente* puntos en la historia de tu proyecto. Para cosas como releases mayores o grandes merges, ¿hay algún modo de marcar esos commits con algo más permanente que un branch?", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "¡Seguro que hay! Los tags de git soportan exactamente este caso de uso -- marcan (bastante) permanentemente determinados commits como \"hitos\" que puedes referenciar como a un branch.", + "", + "Aún más importante, los tags no avanzan cuando se crean nuevos commits. No puedes hacer checkout a un tag y completar el trabajo en ese tag - los tags son marcas fijas en el árbol de commits que designan ciertos puntos.", + "", + "Veamos cómo se ven los tags en práctica..." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Creemos un tag en `C1`, que es nuestro prototipo de la versión 1" + ], + "afterMarkdowns": [ + "¡Ahí está! Bastante simple. Nombramos al tag `v1` y referenciamos explícitamente al commit `C1`. Si no especificas el commit, git va a usar al apuntado por `HEAD`." + ], + "command": "git tag v1 C1", + "beforeCommand": "git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para este nivel, simplemente crea los tags en la visualización final y después haz checkout con `v1`. Observa cómo entras en el estado detached -- esto es porque no puedes hacer commit directamente sobre el tag `v1`.", + "", + "En el próximo nivel vamos a examinar un caso de uso más interesante para los tags." + ] + } + } + ] + }, "pt_BR": { "childViews": [ { @@ -323,7 +383,7 @@ "Criemos uma tag em `C1`, que é nosso protótipo da versão 1" ], "afterMarkdowns": [ - "Aqui! Bem fácil. Nós chamamos a tag de `v1` e referenciamos o commit `C1` explicitamente. Se você chamar o comando sem especificar um commit, o git vai usar seja lá qual commit para o qual o `HEAD` estiver apontando" + "Aqui! Bem fácil. Nós chamamos a tag de `v1` e referenciamos o commit `C1` explicitamente. Se você chamar o comando sem especificar um commit, o git vai usar seja lá qual commit para o qual o `HEAD` estiver apontando." ], "command": "git tag v1 C1", "beforeCommand": "git commit" @@ -341,6 +401,58 @@ } ] }, + "gl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Etiquetas en Git", + "", + "Como aprendiches nas leccións previas, as ramas pódense mover sinxelamente, e xeralmente refírense a distintos commits según vas completando o código. As ramas mutan con facilidade, soen ser temporais, e sempre cambiantes.", + "", + "Se estamos nese caso, podes preguntarte se existe unha forma de marcar *permanentemente* puntos históricos no proxecto. Para cousas como grandes entregas ou grandes merges, ¿existe algunha forma de marcar commits con algo máis permanente que unha rama?", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Acertaches seguro, ¡si que existe! As etiquetas de git foron creadas para ese propósito -- elas marcan de forma (relativamente) permanente algún commits coma se fosen \"marcos das fincas\" (\"milestones\") nun campeiro, e podes facer referencias a elas mellor que o catastro.", + "", + "É moi importante saber que, as etiquetas non avanzan cando se crean novos commits. Non podes facer \"checkout\" nun tag e completar o traballo de esa etiqueta cun commit amend ou rebasándoo -- as etiquetas existen como áncoras na árbore de commits que están pegadas a certos puntos.", + "", + "Vexamos como se comportan as etiquetas na práctica." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Creamos un tag na rama `C1`, que é o noso prototipo da versión 1" + ], + "afterMarkdowns": [ + "¡Ahí o tes!. Sinxelo. Nomeamos a etiqueta de `v1` e referenciamos o commit `C1` explícitamente. Se non indicas o commit, git vai empregar o commit onde está situado o `HEAD`." + ], + "command": "git tag v1 C1", + "beforeCommand": "git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para completar esta tarefa, crea as etiquetas amosadas na visualización do obxectivo, e entón fai checkout en `v1`. Mira que terminas no estado \"Detached HEAD\" -- eso é porque non podes facer commit directamente na etiqueta `v1`.", + "", + "No próximo nivel, examinaremos un caso de uso máis interesante para as etiquetas." + ] + } + } + ] + }, "de_DE": { "childViews": [ { @@ -349,7 +461,7 @@ "markdowns": [ "## Git Tags", "", - "Wie du aus den vorhergehenden Levels weißt sind Branches einfach durch die Gegend zu schieben und zeigen auf verschiedene Commits, während die Arbeit in ihnen fortschreitet. Ein Branch wird oft verändert, manchmal nur temporär, und ist ständig in Bewegung.", + "Wie du aus den vorhergehenden Levels weißt, sind Branches einfach durch die Gegend zu schieben und zeigen auf verschiedene Commits, während die Arbeit in ihnen fortschreitet. Ein Branch wird oft verändert, manchmal nur temporär, und ist ständig in Bewegung.", "", "Da das so ist fragst du dich vielleicht, ob es nicht eine Möglichkeit gibt, eine bestimmte Stelle in deiner Projekt-History *permanent* zu kennzeichnen. Kann man nicht zum Beispiel für große Releases und Meilensteine nicht einen Commit mit etwas festerem kennzeichnen, als mit einem Branch-Namen?", "" @@ -375,7 +487,7 @@ "Lass uns ein Tag bei `C1` anlegen und damit die Version 1 unseres Prototyps markieren." ], "afterMarkdowns": [ - "Peng! Ziemlich einfach. Wir haben das Tag `v1` genannt und lassen es auf `C1` zeigen. Wenn du den Commit weglässt wir das Tag für den Commit erzeugt, auf den `HEAD` zeigt." + "Peng! Ziemlich einfach. Wir haben das Tag `v1` genannt und lassen es auf `C1` zeigen. Wenn du den Commit weglässt, wird das Tag für den Commit erzeugt, auf den `HEAD` zeigt." ], "command": "git tag v1 C1", "beforeCommand": "git commit" @@ -387,7 +499,7 @@ "markdowns": [ "Um diesen Level zu schaffen, erstelle einfach die Tags wie sie in der Zielbeschreibung stehen und mach dann einen Checkout auf `v1`. Beachte wie du dabei in den \"Detached HEAD\" Zustand gehst -- das liegt daran, dass du keine Commits direkt auf das `v1` Tag machen kannst.", "", - "Im nächsten Level schauen wir uns dann interessantere Anwendungsfälle für Tags an." + "Im nächsten Level schauen wir uns dann einen interessanteren Anwendungsfall für Tags an." ] } } @@ -479,7 +591,7 @@ "Создадим тег на `C1`, который будет нашей версией 1" ], "afterMarkdowns": [ - "Готово! Всё просто. Мы назвали тег `v1` и заставили его ссылаться на `C1` явным образом. Если конкретный коммит не указан, гит пометит тегом `HEAD`" + "Готово! Всё просто. Мы назвали тег `v1` и заставили его ссылаться на `C1` явным образом. Если конкретный коммит не указан, гит пометит тегом `HEAD`." ], "command": "git tag v1 C1", "beforeCommand": "git commit" @@ -505,7 +617,7 @@ "markdowns": [ "## Git 태그", "", - "이전 강의에서 배웠듯이, 브랜치는 이동하기 쉽습니다. 작업의 완료, 진행에따라 이리저리 이동하면서 서로다른 커밋을 참조하게 됩니다. 브랜치는 쉽게 변하며 임시적인 것입니다 항상 바뀌고 있죠.", + "이전 강의에서 배웠듯이, 브랜치는 이동하기 쉽습니다. 작업의 완료, 진행에 따라 이리저리 이동하면서 서로 다른 커밋을 참조하게 됩니다. 브랜치는 쉽게 변하며 임시적인 것입니다 항상 바뀌고 있죠.", "", "이런 상황에서, 여러분은 여러분의 프로젝트의 역사(작업 이력)에서 중요한 지점들에 *영구적으로* 표시를 할 방법이 없을까 궁금할것입니다. 주요 릴리즈나 큰 브랜치 병합(merge)이 있을때가 그런 상황이겠군요. 이런 상황에 커밋들을 표시할 브랜치보다 영구적인 방법이 있을까요?", "" @@ -600,6 +712,110 @@ } } ] + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Tag trong Git", + "", + "Qua các bài học trước, bạn đã biết được rằng rất dễ dàng để di chuyển qua lại giữa các nhánh và chúng thường tham chiếu đến các commit khác nhau trong quá trình ta làm việc trên chúng. Nhánh thường dễ biết đổi, thường chỉ là tạm thời và chúng luôn như vậy.", + "", + "Nếu như vậy thì bạn có thể sẽ thắc mắc liệu có cách nào để đánh dấu *vĩnh viễn* một thời điểm nào đó trong lịch sử làm việc không? Khi mà dự án càng ngày càng mở rộng và merge thì diễn ra liên tục, vậy thì có cách nào để đánh dấu những commit đó một cách cố định hơn nhánh không?", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Tất nhiên là có chứ! Git có các tag(thẻ) để hỗ trợ vấn đề này -- chúng (bằng cách nào đó) đánh dấu vĩnh viễn một commit cụ thể nào đó như một \"cột mốc\" mà sau đó bạn có thể tham chiếu đến như với nhánh.", + "", + "Quan trọng hơn là, khi ta commit thì chúng không hề bị di chuyển. Bạn không thể \"check out\" một tag rồi làm việc trên đó -- tag giống như là mỏ neo để chỉ định một điểm cụ thể nào dó trên cây lịch sử.", + "", + "Cùng xem tag thực tế là như thế nào nào." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Hãy thử tạo một thẻ ở commit `C1` chỉ định rằng đây là phiên bản thứ nhất của ta." + ], + "afterMarkdowns": [ + "Đó! Đơn giản như đan rổ. Ta tạo ra thẻ `v1` và tham chiếu đến commit `C1`. Nếu bạn không chỉ định commit, git sẽ gắn thẻ vào commit mà `HEAD` đang trỏ tới" + ], + "command": "git tag v1 C1", + "beforeCommand": "git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Trong cấp độ này hãy tạo ra một thẻ tại vị trí chỉ định và chuyển sang `v1`. Để ý rằng bạn sẽ chuyến sang trạng thái tách biệt `HEAD` -- bởi vì bạn không thể tham chiếu đến thẻ `v1`.", + "", + "Sang cấp độ tới ta sẽ xem xét một vài cách hay ho để dùng thẻ." + ] + } + } + ] + }, + "sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Tagi", + "", + "Kot si se naučil v prejšnjih lekcijah, so branchi enostavni za premikat okoli in pogosto kažejo na različne commite in delo za njimi. Veliko se spreminjajo in združujejo, pogosto le začasno.", + "", + "Če je temu res tako, se morda sprašuješ, če obstaja kak način, ki bi *trajno* označil točke v zgodovini projekta. Za stvari kot so večji release-i ali pomembni merge-i, ali obstaja način, ki je trajnejši kot branch?", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Itak da je! Git tagi podpirajo točno ta primer uporabe -- oni trajno (do neke mere) označijo določene commite kot \"mejnike\" na katere se lahko sklicujemo kot na branche.", + "", + "Toda še pomembneje, oni se ne premikajo, ko se ustvarjajo novi commiti. Ne moreš \"checkoutat\" tag in nato končati delo na tem tagu -- tagi obstajajo kot sidra na drevesu commitov, ki označujejo določene točke.", + "", + "Poglejmo kako to izgleda v praksi." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Poizkusimo narediti tag na `C1`, ki je recimo naša prva različica prototipa." + ], + "afterMarkdowns": [ + "Tako! Kar enostavno. Tag smo poimenovali `v1` in se sklicuje na commit `C1`. Če ne navedeš commita, bo git postavil tag tam, kjer je trenutno `HEAD`." + ], + "command": "git tag v1 C1", + "beforeCommand": "git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Za to stopnjo ustvari tage kot so določeni na ciljnem prikazu in nato checkoutaj `v1`. Opazil boš, kako prideš v stanje ločenega `HEAD-a` -- to je zato, ker ne moreš commitat direktno na `v1` tag.", + "", + "V naslednji stopnji si bomo pogledali zanimivejši primer za uporabo tagov." + ] + } + } + ] } } }; diff --git a/src/levels/rampup/cherryPick.js b/src/levels/rampup/cherryPick.js index ce0094a3..8976475d 100644 --- a/src/levels/rampup/cherryPick.js +++ b/src/levels/rampup/cherryPick.js @@ -1,4 +1,4 @@ -exports.level = { +exports.level = { "goalTreeString": "%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C7%27%22%2C%22id%22%3A%22master%22%7D%2C%22bugFix%22%3A%7B%22target%22%3A%22C3%22%2C%22id%22%3A%22bugFix%22%7D%2C%22side%22%3A%7B%22target%22%3A%22C5%22%2C%22id%22%3A%22side%22%7D%2C%22another%22%3A%7B%22target%22%3A%22C7%22%2C%22id%22%3A%22another%22%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C4%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C4%22%7D%2C%22C5%22%3A%7B%22parents%22%3A%5B%22C4%22%5D%2C%22id%22%3A%22C5%22%7D%2C%22C6%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C6%22%7D%2C%22C7%22%3A%7B%22parents%22%3A%5B%22C6%22%5D%2C%22id%22%3A%22C7%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C3%27%22%7D%2C%22C4%27%22%3A%7B%22parents%22%3A%5B%22C3%27%22%5D%2C%22id%22%3A%22C4%27%22%7D%2C%22C7%27%22%3A%7B%22parents%22%3A%5B%22C4%27%22%5D%2C%22id%22%3A%22C7%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%7D", "solutionCommand": "git cherry-pick C3 C4 C7", "compareOnlyMasterHashAgnostic": true, @@ -12,25 +12,35 @@ "de_DE": "Einführung Cherry-picking", "ja" : "cherry-pick入門", "es_AR": "Introducción a cherry-pick", + "es_ES": "Introducción a cherry-pick", "pt_BR": "Introdução ao cherry-pick", + "gl" : "Introuducción a cherry-pick", "zh_CN": "Git Cherry-pick", "zh_TW": "介紹 cherry-pick", "ru_RU": "Введение в Cherry-pick", "ko" : "Cherry-pick 소개", - "uk": "Знайомство з cherry-pick" + "uk": "Знайомство з cherry-pick", + "vi" : "Giới thiệu về cherry-pick", + "sl_SI": "Uvod v Cherry-pick", + "pl": "Wprowadzenie do Cherry-pick'ingu" }, "hint": { - "fr_FR": "git cherry-pick suivis par les noms de commits", + "fr_FR": "git cherry-pick suivi par les noms de commits", "en_US": "git cherry-pick followed by commit names!", "de_DE": "git cherry-pick gefolgt von Commit-Namen.", "ja" : "git cherry-pickの後にコミット名を追加", "es_AR": "git cherry-pick seguido de los nombres de los commits", + "es_ES": "git cherry-pick seguido de los nombres de los commits", "pt_BR": "git cherry-pick seguido dos nomes dos commits", + "gl" : "git cherry-pick seguido das referencias a commits", "zh_CN": "git cherry-pick 后面要跟提交的名字", "zh_TW": "git cherry-pick 後面要接著 commit 的名稱", "ru_RU": "git cherry-pick основывается на именах коммитов!", "ko" : "커밋의 이름들로 git cherry-pick 하세요!", - "uk": "git cherry-pick базується на іменах комітів!" + "uk": "git cherry-pick базується на іменах комітів!", + "vi" : "git cherry-pick sau đó là tên commit!", + "sl_SI": "git cherry-pick nato pa imena commitov.", + "pl": "git cherry-pick a po nim nazwy commitów!", }, "startDialog": { "en_US": { @@ -70,20 +80,20 @@ "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Here's a repository where we have some work in branch `side` that we want to copy to `master`. This could be accomplished through a rebase (which we have already learned), but let's see how cherry-pick performs." + "Here's a repository where we have some work in branch `side` that we want to copy to `main`. This could be accomplished through a rebase (which we have already learned), but let's see how cherry-pick performs." ], "afterMarkdowns": [ "That's it! We wanted commits `C2` and `C4` and git plopped them down right below us. Simple as that!" ], "command": "git cherry-pick C2 C4", - "beforeCommand": "git checkout -b side; git commit; git commit; git commit; git checkout master; git commit;" + "beforeCommand": "git checkout -b side; git commit; git commit; git commit; git checkout main; git commit;" } }, { "type": "ModalAlert", "options": { "markdowns": [ - "To complete this level, simply copy some work from the three branches shown into master. You can see which commits we want by looking at the goal visualization.", + "To complete this level, simply copy some work from the three branches shown into main. You can see which commits we want by looking at the goal visualization.", "" ] } @@ -127,20 +137,20 @@ "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Ici le dépôt que nous avons contient du travail dans la branche `side`, que nous voulons copier dans `master`. Cela pourrait être fait avec un rebase (que nous avons déjà appris), mais voyons comment cherry-pick fonctionne." + "Ici le dépôt que nous avons contient du travail dans la branche `side`, que nous voulons copier dans `main`. Cela pourrait être fait avec un rebase (que nous avons déjà appris), mais voyons comment cherry-pick fonctionne." ], "afterMarkdowns": [ "Voilà ! Nous voulions les commits `C2` et `C4` et git les a fait apparaître juste sous nos jambes. Aussi simple que ça !" ], "command": "git cherry-pick C2 C4", - "beforeCommand": "git checkout -b side; git commit; git commit; git commit; git checkout master; git commit;" + "beforeCommand": "git checkout -b side; git commit; git commit; git commit; git checkout main; git commit;" } }, { "type": "ModalAlert", "options": { "markdowns": [ - "Pour finir ce niveau, copiez simplement le travail désigné dans la branche master. Vous pouvez voir les commits que nous souhaitons avoir en regardant dans la fenêtre d'objectif.", + "Pour finir ce niveau, copiez simplement le travail désigné dans la branche main. Vous pouvez voir les commits que nous souhaitons avoir en regardant dans la fenêtre d'objectif.", "" ] } @@ -171,7 +181,7 @@ "", "El primer comando en esta serie se llama `git cherry-pick`. Tiene la siguiente forma:", "", - "* `git cherry-pick <...>`", + " `git cherry-pick <...>`", "", "Es una manera bastante directa de decir que querés copiar una serie de commits sobre tu ubicación actual (`HEAD`). Personalmente amo `cherry-pick` porque hay muy poca magia involucrada y es bastante simple de entender.", "", @@ -184,20 +194,77 @@ "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Acá tenemos un repositorio con algo de trabajo en la rama `side` que queremos copiar a `master`. Podríamos lograrlo con un rebase (y ya aprendimos cómo), pero veamos cómo se comporta cherry-pick." + "Acá tenemos un repositorio con algo de trabajo en la rama `side` que queremos copiar a `main`. Podríamos lograrlo con un rebase (y ya aprendimos cómo), pero veamos cómo se comporta cherry-pick." ], "afterMarkdowns": [ "¡Eso es todo! Queríamos los commits `C2` y `C4` y git los aplicó justo donde estábamos. ¡Tan simple como eso!" ], "command": "git cherry-pick C2 C4", - "beforeCommand": "git checkout -b side; git commit; git commit; git commit; git checkout master; git commit;" + "beforeCommand": "git checkout -b side; git commit; git commit; git commit; git checkout main; git commit;" } }, { "type": "ModalAlert", "options": { "markdowns": [ - "Para completar este nivel, simplemente copiá algo de trabajo desde otras tres ramas a master. Podés ver qué commits queremos en la visualización del objetivo.", + "Para completar este nivel, simplemente copiá algo de trabajo desde otras tres ramas a main. Podés ver qué commits queremos en la visualización del objetivo.", + "" + ] + } + } + ] + }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Moviendo el trabajo por ahí", + "", + "Hasta ahora cubrimos lo básico de git -- hacer commits, crear ramas, y movernos por el árbol de commits. Estos conceptos alcanzan para aprovechar el 90% del poder de los repositorios de git y cubrir las necesidades principales de los desarrolladores.", + "", + "El 10% restante, sin embargo, puede ser bastante útil en flujos de trabajo complejos (o cuando te metiste en algún problema complicado). El próximo concepto que vamos a cubrir es el de \"mover el trabajo por ahí\" -- en otras palabras, una forma que tienen los desarrolladores de decir \"Quiero este trabajo aquí y este otro allí\" de una manera precisa, elocuente y flexible.", + "", + "Puede parecer un montón, pero es un concepto bastante simple." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Cherry-pick", + "", + "El primer comando en esta serie se llama `git cherry-pick`. Tiene la siguiente forma:", + "", + " `git cherry-pick <...>`", + "", + "Es una manera bastante directa de decir que quieres copiar una serie de commits sobre tu ubicación actual (`HEAD`). Personalmente amo `cherry-pick` porque hay muy poca magia involucrada y es bastante simple de entender.", + "", + "¡Veamos una demo!", + "" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "A continuación tenemos un repositorio con algo de trabajo en la rama `side` que queremos copiar a `main`. Podríamos lograrlo con un rebase (y ya aprendimos cómo), pero veamos cómo se comporta cherry-pick." + ], + "afterMarkdowns": [ + "¡Eso es todo! Queríamos los commits `C2` y `C4` y git los aplicó justo donde estábamos. ¡Tan simple como eso!" + ], + "command": "git cherry-pick C2 C4", + "beforeCommand": "git checkout -b side; git commit; git commit; git commit; git checkout main; git commit;" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para completar este nivel, simplemente copia algo de trabajo desde otras tres ramas a main. Puedes ver qué commits queremos en la visualización del objetivo.", "" ] } @@ -210,7 +277,7 @@ "type": "ModalAlert", "options": { "markdowns": [ - "## Movendo trabalho por aí", + "## Movendo o trabalho por aí", "", "Por enquanto nós abordamos o básico do Git -- commitar, criar ramos, e mover-se pela árvore. Apenas esses conceitos já são suficientes para utilizar 90% do poder dos repositórios Git, e cobrem as principais necessidades dos desenvolvedores.", "", @@ -241,20 +308,77 @@ "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Aqui está um repositório onde temos algum trabalho no ramo `side` que desejamos copiar para o `master`. Isso poderia ser obtido por meio de um rebase (que já aprendemos), mas vamos ver como o cherry-pick se sai." + "Aqui está um repositório onde temos algum trabalho no ramo `side` que desejamos copiar para o `main`. Isso poderia ser obtido por meio de um rebase (que já aprendemos), mas vamos ver como o cherry-pick se sai." ], "afterMarkdowns": [ "É isso! Queríamos os commits `C2` e `C4` e o git os inseriu logo abaixo de nós. Simples assim!" ], "command": "git cherry-pick C2 C4", - "beforeCommand": "git checkout -b side; git commit; git commit; git commit; git checkout master; git commit;" + "beforeCommand": "git checkout -b side; git commit; git commit; git commit; git checkout main; git commit;" } }, { "type": "ModalAlert", "options": { "markdowns": [ - "Para completar este nível, simplesmente copie algum trabalho dos outros três ramos para o master. Você pode ver quais commits queremos copiar na visualização do objetivo.", + "Para completar este nível, simplesmente copie algum trabalho dos outros três ramos para o main. Você pode ver quais commits queremos copiar na visualização do objetivo.", + "" + ] + } + } + ] + }, + "gl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Movendo traballo por ahí", + "", + "Ata agora cubrimos o uso básico de git -- facer commit, crear ramas, e moverse pola árbore. Estes conceptos chegan para aproveitar o 90% do poder dos repositorios de git e cubrilas necesidades principais dos desenvolvedores.", + "", + "O 10% restante, ademáis, poden ser extremadamente útiles nos fluxos de traballo complexos (ou cando te meteches nalgún problema complicado). O próximo concepto que imos abordar é \"movendo o traballo por ahí\" -- noutras verbas, unha forma que teñen os desenvolvedores de dicir \"eu quero este traballo aquí, e aquel alí\" de forma precisa, elocuente e flexible.", + "", + "Eso pode ser moito, pero os conceptos son simples." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Cherry-pick", + "", + "O primeiro comando desta serie é `git cherry-pick`. O comando emprégase da seguinte forma:", + "", + "* `git cherry-pick <...>`", + "", + "Trátase dunha forma bastante directa de dicir que queres copiar unha serie de commits sobre a túa ubicación actual (`HEAD`). Eu persoalmente adoro `cherry-pick` porque hai moita maxia envolta e é un funcionamento sinxelo de entender.", + "", + "Vexamos unha demostración!", + "" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Aquí está un repositorio onde hai algún traballo na rama `side` que desexamos copiar para a rama `main`. Iso podería ser obtido por medio dun rebase (que xa aprendemos), pero imos ver como o resolve cherry-pick." + ], + "afterMarkdowns": [ + "¡Eso é! Queríamos os commits `C2` e `C4` e git insertounos por baixo de nós. ¡Moi sinxelo!" + ], + "command": "git cherry-pick C2 C4", + "beforeCommand": "git checkout -b side; git commit; git commit; git commit; git checkout main; git commit;" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para completar este nivel, copia algo de traballo das outras ramas na main. Podes ver qué commits queremos copiar na visualización do obxectivo.", "" ] } @@ -298,20 +422,20 @@ "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "這裡有一個 repo,在 `side` branch 中,我們有一些 commit 想要複製到 `master` branch 上,這可以透過一個 rebase 來完成(我們之前已經學到了),但是讓我們看看 `git cherry-pick` 怎麼做。" + "這裡有一個 repo,在 `side` branch 中,我們有一些 commit 想要複製到 `main` branch 上,這可以透過一個 rebase 來完成(我們之前已經學到了),但是讓我們看看 `git cherry-pick` 怎麼做。" ], "afterMarkdowns": [ "就是那樣!我們複製了 `C2` 以及 `C4` 並且把它們放到我們的後面,很簡單吧!" ], "command": "git cherry-pick C2 C4", - "beforeCommand": "git checkout -b side; git commit; git commit; git commit; git checkout master; git commit;" + "beforeCommand": "git checkout -b side; git commit; git commit; git commit; git checkout main; git commit;" } }, { "type": "ModalAlert", "options": { "markdowns": [ - "要完成這個關卡,只需要從三個 branch 複製幾個 commit 到 `master` 下面,你可以從視覺化的目標看到我們需要哪些 commit。", + "要完成這個關卡,只需要從三個 branch 複製幾個 commit 到 `main` 下面,你可以從視覺化的目標看到我們需要哪些 commit。", "" ] } @@ -328,7 +452,7 @@ "", "到现在我们已经学习了 Git 的基础知识 —— 提交、分支以及在提交树上移动。 这些概念涵盖了 Git 90% 的功能,同样也足够满足开发者的日常需求 ", "", - "然而, 剩余的 10% 在处理复杂的工作流时(或者当你陷入困惑时)可能就显示尤为重要了。接下来要讨论的这个话题是“整理提交记录” —— 开发人员有时会说“我想要把这个提交放到这里, 那个提交放到刚才那个提交的后面”, 而接下来就讲的就是它的实现方式,非常清晰、灵活,还很生动。", + "然而, 剩余的 10% 在处理复杂的工作流时(或者当你陷入困惑时)可能就显得尤为重要了。接下来要讨论的这个话题是“整理提交记录” —— 开发人员有时会说“我想要把这个提交放到这里, 那个提交放到刚才那个提交的后面”, 而接下来就讲的就是它的实现方式,非常清晰、灵活,还很生动。", "", "看起来挺复杂, 其实是个很简单的概念。" ] @@ -354,20 +478,20 @@ "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "这里有一个仓库, 我们想将 `side` 分支上的工作复制到 `master` 分支,你立刻想到了之前学过的 `rebase` 了吧?但是咱们还是看看 `cherry-pick` 有什么本领吧。" + "这里有一个仓库, 我们想将 `side` 分支上的工作复制到 `main` 分支,你立刻想到了之前学过的 `rebase` 了吧?但是咱们还是看看 `cherry-pick` 有什么本领吧。" ], "afterMarkdowns": [ "这就是了!我们只需要提交记录 `C2` 和 `C4`,所以 Git 就将被它们抓过来放到当前分支下了。 就是这么简单!" ], "command": "git cherry-pick C2 C4", - "beforeCommand": "git checkout -b side; git commit; git commit; git commit; git checkout master; git commit;" + "beforeCommand": "git checkout -b side; git commit; git commit; git commit; git checkout main; git commit;" } }, { "type": "ModalAlert", "options": { "markdowns": [ - "要通过此关, 只需要简单的将三个分支中的提交记录复制到 master 上就可以了。目标窗口展示了我们想要哪些提交记录,如果你不小心关掉了的话,通过 `show goal` 命令可以打开,左上角也有“显示目标按钮”", + "要通过此关, 只需要简单的将三个分支中的提交记录复制到 main 上就可以了。目标窗口展示了我们想要哪些提交记录,如果你不小心关掉了的话,通过 `show goal` 命令可以打开,左上角也有“显示目标按钮”", "" ] } @@ -382,7 +506,7 @@ "markdowns": [ "## Inhalte verschieben", "", - "Bis jetzt haben wir uns die Grundlagen von Git angeschaut -- comitten, verzweigen und sich im Commit-Baum bewegen. Nur damit lässt sich schon 90% der Macht von Git-Repositories nutzen und die meisten Anforderungen von Entwicklern erfüllen.", + "Bis jetzt haben wir uns die Grundlagen von Git angeschaut -- comitten, verzweigen und sich im Commit-Baum bewegen. Nur damit lässt sich schon 90% der Macht von Git-Repositorys nutzen und die meisten Anforderungen von Entwicklern erfüllen.", "", "Die übrigen 10% jedoch können in komplexeren Abläufen sehr hilfreich sein (oder wenn man sich in eine schwierige Lage manövriert hat). Das nächste was wir uns anschauen, ist, Inhalte durch den Commit-Baum zu schieben. Es gibt dem Entwickler die Möglichkeit in präziser, eloquenter Manier zu sagen \"Ich will diese Inhalte hier und diese dort haben\".", "", @@ -400,7 +524,7 @@ "", "* `git cherry-pick <...>`", "", - "Er ist eine einfache Möglichkeit um auszudrücken, dass du eine Folge von Commits unter deinen aktuellen Checkout (also `HEAD`) hängen möchtest. Ich persönlich liebe `cherry-pick`, weil es wenig Magic enthält und einfach zu verstehen ist.", + "Er ist eine einfache Möglichkeit um auszudrücken, dass du eine Folge von Commits unter deinen aktuellen Checkout (also `HEAD`) hängen möchtest. Ich persönlich liebe `cherry-pick`, weil es wenig Magie enthält und einfach zu verstehen ist.", "", "Schauen wir's uns mal an.", "" @@ -411,20 +535,20 @@ "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Hier haben wir ein Repository mit einigem Zeugs im Branch `side`, das wir in den Branch `master` kopieren wollen. Das könnten wir mit einem Rebase machen (wie bereits gesehen), aber schauen wir mal wie das mit `cherry-pick` geht." + "Hier haben wir ein Repository mit einigem Zeugs im Branch `side`, das wir in den Branch `main` kopieren wollen. Das könnten wir mit einem Rebase machen (wie bereits gesehen), aber schauen wir mal, wie das mit `cherry-pick` geht." ], "afterMarkdowns": [ - "Das war's! Wir wollten die commits `C2` und `C4` und Git hat die einfach unter unseren aktuellen Checkout kopiert. So einfach ist das." + "Das war's! Wir wollten die Commits `C2` und `C4` und Git hat die einfach unter unseren aktuellen Checkout kopiert. So einfach ist das." ], "command": "git cherry-pick C2 C4", - "beforeCommand": "git checkout -b side; git commit; git commit; git commit; git checkout master; git commit;" + "beforeCommand": "git checkout -b side; git commit; git commit; git commit; git checkout main; git commit;" } }, { "type": "ModalAlert", "options": { "markdowns": [ - "Um diesen Level zu schaffen musst du einfach nur einige Commits aus den drei gezeigten Branches in den `master` kopieren. Der Zielbaum zeigt dir, welche.", + "Um diesen Level zu schaffen musst du einfach nur einige Commits aus den drei gezeigten Branches in den `main` kopieren. Der Zielbaum zeigt dir, welche.", "" ] } @@ -468,13 +592,13 @@ "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "このリポジトリには、現在`side`ブランチから`master`にコピーしたいコードがあります。この前に学んだrebaseコマンドでも実現可能ですが、ここではcherry-pickの動作を見ていきましょう。" + "このリポジトリには、現在`side`ブランチから`main`にコピーしたいコードがあります。この前に学んだrebaseコマンドでも実現可能ですが、ここではcherry-pickの動作を見ていきましょう。" ], "afterMarkdowns": [ "これだけで終わりです!コミット`C2` と `C4`を取得したかったわけですが、gitが現在の位置の直下に落としてくれました。単純ですね!" ], "command": "git cherry-pick C2 C4", - "beforeCommand": "git checkout -b side; git commit; git commit; git commit; git checkout master; git commit;" + "beforeCommand": "git checkout -b side; git commit; git commit; git commit; git checkout main; git commit;" } }, { @@ -525,13 +649,13 @@ "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Вот репозиторий, где есть некие изменения в ветке `side`, которые мы хотим применить и в ветку `master`. Мы можем сделать это при помощи команды rebase, которую мы уже прошли, но давай посмотрим, как cherry-pick справится с этой задачей." + "Вот репозиторий, где есть некие изменения в ветке `side`, которые мы хотим применить и в ветку `main`. Мы можем сделать это при помощи команды rebase, которую мы уже прошли, но давай посмотрим, как cherry-pick справится с этой задачей." ], "afterMarkdowns": [ "Вуаля! Мы хотели перенести коммиты `C2` и `C4`, Git дал нам их там, где они нужны. Всё просто!" ], "command": "git cherry-pick C2 C4", - "beforeCommand": "git checkout -b side; git commit; git commit; git commit; git checkout master; git commit;" + "beforeCommand": "git checkout -b side; git commit; git commit; git commit; git checkout main; git commit;" } }, { @@ -545,7 +669,7 @@ } ] }, - "ko": { + "ko": { "childViews": [ { "type": "ModalAlert", @@ -555,9 +679,9 @@ "", "지금까지 우리는 git의 기초를 배웠습니다. -- 커밋을하고, 브랜치를 만들고, 소스 트리 여기저기를 돌아다녔습니다. 이런 개념들을 아는 것만으로도 git repository의 힘을 90%이상 사용하고 개발자들이 필요로하는 작업의 대부분을 할 수 있습니다.", "", - "그 나머지 10% 기능이, 복잡한 작업(또는 작업중 막혔을때)중에 꽤 유용할 수 있습니다. 이제 배워 볼 다음 개념은 \"작업을 여기저로 올기기\" 다시 말해, 개발자들의 언어로 \"이 일은 여기에 저 일은 저기에 두고 싶어\" 정확하고 우아하고 유연하게.", + "그 나머지 10% 기능이, 복잡한 작업(또는 작업중 막혔을때) 중에 꽤 유용할 수 있습니다. 이제 배워 볼 다음 개념은 \"작업을 여기저로 옮기기\" 다시 말해, 개발자들의 언어로 \"이 일은 여기에, 저 일은 저기에 두고 싶어\" 정확하고 우아하고 유연하게.", "", - "다소 과해 보일 수 있는데, 간단한 개념입니다." + "다소 과해 보일 수 있지만, 간단한 개념입니다." ] } }, @@ -582,20 +706,20 @@ "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "여기 repository가 있습니다. `master`와 master로 복사하고 싶은 작업이 있는 브랜치 `side`가 있습니다. 이것은 rebase를 통해서 할 수 있습니다(이미 배운), 하지만 체리-픽이 이 작업을 어떻게 수행하는지 확인해 봅시다." + "여기 repository가 있습니다. `main` 으로 복사하고 싶은 작업이 있는 브랜치 `side`가 있습니다. 이것은 rebase를 통해서 할 수 있습니다(이미 배운), 하지만 체리-픽이 이 작업을 어떻게 수행하는지 확인해 봅시다." ], "afterMarkdowns": [ "됬습니다! 우리는 `C2`와 `C4` 커밋을 원했고 git이 우리가 원하는 곳 바로 밑에 톡 떨어뜨려 줬습니다. 아주 간단하죠!" ], "command": "git cherry-pick C2 C4", - "beforeCommand": "git checkout -b side; git commit; git commit; git commit; git checkout master; git commit;" + "beforeCommand": "git checkout -b side; git commit; git commit; git commit; git checkout main; git commit;" } }, { "type": "ModalAlert", "options": { "markdowns": [ - "이 레벨을 통과하기 위해서는 몇개의 작업을 세개의 브랜치들에서 master로 복사해와야합니다. 어떤 커밋들이 필요한지는 goal을 보고 확인하면 됩니다.", + "이 레벨을 통과하기 위해서는 몇개의 작업을 세개의 브랜치들에서 `main` 브랜치로 복사해와야합니다. 어떤 커밋들이 필요한지는 goal을 보고 확인하면 됩니다.", "" ] } @@ -639,25 +763,196 @@ "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Ми бачимо репозиторій де є певні зміни в гілці `side` які ми хочемо скопіювати в `master`. Для цього можна використати rebase (який ми вже вивчили), але подивимось як з цим впорається cherry-pick." + "Ми бачимо репозиторій де є певні зміни в гілці `side` які ми хочемо скопіювати в `main`. Для цього можна використати rebase (який ми вже вивчили), але подивимось як з цим впорається cherry-pick." ], "afterMarkdowns": [ "Овва! Ми хотіли коміти `C2` та `C4` і git додав їх до поточного розташування. Просто й доступно!" ], "command": "git cherry-pick C2 C4", - "beforeCommand": "git checkout -b side; git commit; git commit; git commit; git checkout master; git commit;" + "beforeCommand": "git checkout -b side; git commit; git commit; git commit; git checkout main; git commit;" } }, { "type": "ModalAlert", "options": { "markdowns": [ - "Щоб пройти це рівень, просто скопіюй якісь зміни з трьох гілок показаних на діаграмі в master. В візуалізації видно які коміти потрібно скопіювати.", + "Щоб пройти це рівень, просто скопіюй якісь зміни з трьох гілок показаних на діаграмі в main. В візуалізації видно які коміти потрібно скопіювати.", "" ] } } ] - } + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Mang đi kéo về", + "", + "Cho đến giờ thì ta đã nắm được cơ bản về git -- commit, rẽ nhánh, và dịch chuyển qua lại trên cây mã nguồn. Chừng ấy khái niệm là đã đủ để tác động đến 90% sức mạnh của kho chứa git và các chức nawmg cần thiết cho nhà phát triển phần mềm.", + "", + "Tuy nhiên 10% còn lại thì lại khá hữu ích trong các quy trình làm việc phức tạp (hoặc khi bạn vướng phải tình huống khó khăn). The next concept we're going to cover is \"chỉnh lý các bản ghi\" -- đó là cách để nhà phát triển nói rằng\"Tôi muốn lấy bản ghi ở đây và cả bản ghi ở đó\" một cách chính xác, linh hoạt và sống động.", + "", + "Nghe thì có vẻ phức tạp, nhưng thực ra khái niệm này khá đơn giản." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Cherry-pick", + "", + "Lệnh đầu tiên của loạt bài này là `git cherry-pick`, dạng lệnh là::", + "", + "* `git cherry-pick <...>`", + "", + "Đó là cách rất trực tiếp để copy một loạt commit xuống dưới vị trí hiện tại của bạn (`HEAD`). Cá nhân tôi thì rất thích `cherry-pick` bởi tính tiện dụng và dễ hiểu của nó.", + "", + "Hãy xem qua một ví dụ!", + "" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Ở đây ta có một kho chứa mà ta muốn sao chép thành quả công việc từ nhánh `side` sang nhánh `main`. Có thể dùng rebase để làm việc này (kỹ thuật mà ta đã học), nhưng hãy xem thử cherry-pick làm điều này ra sao." + ], + "afterMarkdowns": [ + "Thế thôi! Chúng ta chỉ cần các commit `C2` và` C4`, vì vậy Git sẽ lấy chúng và đặt chúng dưới nhánh hiện tại. Thật đơn giản!" + ], + "command": "git cherry-pick C2 C4", + "beforeCommand": "git checkout -b side; git commit; git commit; git commit; git checkout main; git commit;" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Để hoàn thành cấp độ này, hãy copy thành quả công việc từ 3 nhánh khác vào main. Bạn có thể nhìn vào mô tả mục tiêu để biết chúng ta cần những commit nào.", + "" + ] + } + } + ] + }, + "sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Premikanje dela naokoli", + "", + "Zaenkrat smo pokrili osnove gita -- commitanje, branchanje in pomikanje po drevesu. Samo te koncepti so dovolj za koriščenje 90% moči git repozitorijev in pokrijejo večino potreb razvijalcev.", + "", + "Preostalih 10% pa je lahko kar uporabnih med reševanjem kompleksnejših situacij (ali ko ste zašli v zagato). Naslednji koncept, ki ga bomo pokrili je \"premikanje dela naokoli\" -- z drugimi besedami, tako razvijalci rečejo \"Rad bi to delo tu in tisto delo tam\" na natančen, zgovoren in prilagodljiv način.", + "", + "Morda se zdi veliko, a gre za preprost koncept." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Cherry-pick", + "", + "Prvi ukaz v zaporedju je `git cherry-pick`. Je sledeče oblike:", + "", + "* `git cherry-pick <...>`", + "", + "Gre za jasen način, da povemo, da bi radi skopirali zaporedje commitov pod trenutno lokacijo (`HEAD`). Sam imam rad `cherry-pick`, ker je vključeno le malo čarovnije in je preprost za razumet.", + "", + "Poglejmo predstavitev!", + "" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Tu je repozitorij, kjer imamo nekaj dela na branchu `side`, ki bi ga radi skopirali na `main`. To bi lahko dosegli z rebase-om (kar smo se že naučili), ampak poglejmo kako se odreže cherry-pick." + ], + "afterMarkdowns": [ + "To je to! Želeli smo commita `C2` in `C4` in git ju je prilimal točno pod nas. Preprosto!" + ], + "command": "git cherry-pick C2 C4", + "beforeCommand": "git checkout -b side; git commit; git commit; git commit; git checkout main; git commit;" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Za končanje te stopnje enostavno skopiraj nekaj dela iz predstavljenih treh branchev v main. V priloženi vizualizaciji lahko vidiš katere commite.", + "" + ] + } + } + ] + }, + "pl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Przenoszenie pracy", + "", + "Do tej pory zajmowaliśmy się podstawami gita - commitowaniem, gałęziami i poruszaniem się w drzewie źródłowym. Tylko te koncepcje wystarczą, aby wykorzystać 90% mocy repozytoriów git i pokryć główne potrzeby deweloperów.", + "", + "Pozostałe 10% może być jednak dość użyteczne podczas niecodziennych zadań (lub gdy o czymś zapomniałeś). Kolejna koncepcja, którą zamierzamy omówić to \"przenoszenie pracy\" - innymi słowy, jest to sposób, w jaki deweloperzy mogą powiedzieć: \"Chcę te zmiany tu i tam\" w precyzyjny, wymowny i elastyczny sposób.", + "", + "To może wydawać się sporo, ale to prosta koncepcja." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Cherry-pick", + "", + "Pierwsza komenda w tej serii nazywa się `git cherry-pick`. Przyjmuje ona następującą formę:", + "", + "* `git cherry-pick <...>`", + "", + "Jest to bardzo prosty sposób określenia jakie zmiany poniżej swojej obecnej lokalizacji (`HEAD`) chciałbyś przenieść. Osobiście uwielbiam `cherry-pick'ing`, ponieważ jest to proste jak budowa cepa.", + "", + "Zobaczmy demo!", + "" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Mamy tutaj repozytorium, gdzie mamy trochę pracy na gałęzi `side`, które chcemy skopiować do gałęzi `main`. Można by to osiągnąć dzięki komendy rebase'owi (którego już się nauczyliśmy), ale zobaczmy, jak działa cherry-pick." + ], + "afterMarkdowns": [ + "To jest to! Chcieliśmy aby commity `C2` i `C4` i git wziął i dodał do `main`. Bułka z masłem!" + ], + "command": "git cherry-pick C2 C4", + "beforeCommand": "git checkout -b side; git commit; git commit; git commit; git checkout main; git commit;" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Aby ukończyć ten poziom, po prostu skopiuj część pracy z trzech pokazanych gałęzi `main`. Commity, które należy skopiować znajdują się na wizualizacji celu.", + "" + ] + } + } + ] + }, } }; diff --git a/src/levels/rampup/detachedHead.js b/src/levels/rampup/detachedHead.js index 887c635a..d001b03b 100644 --- a/src/levels/rampup/detachedHead.js +++ b/src/levels/rampup/detachedHead.js @@ -1,32 +1,42 @@ exports.level = { "goalTreeString": "{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\"},\"bugFix\":{\"target\":\"C4\",\"id\":\"bugFix\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C3\"],\"id\":\"C4\"}},\"HEAD\":{\"target\":\"C4\",\"id\":\"HEAD\"}}", "solutionCommand": "git checkout C4", - "startTree": "{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\"},\"bugFix\":{\"target\":\"C4\",\"id\":\"bugFix\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C3\"],\"id\":\"C4\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}", + "startTree": "{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\"},\"bugFix\":{\"target\":\"C4\",\"id\":\"bugFix\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C3\"],\"id\":\"C4\"}},\"HEAD\":{\"target\":\"bugFix\",\"id\":\"HEAD\"}}", "name": { "en_US": "Detach yo' HEAD", "es_AR": "Desatacheá tu HEAD", + "es_ES": "Desatachea tu HEAD", "pt_BR": "Solte a sua cabeça", - "fr_FR": "Détachez votre HEAD", + "gl" : "Abandona o teu HEAD", + "fr_FR": "Détacher votre HEAD", "zh_CN": "分离 HEAD", "zh_TW": "分離 HEAD", "de_DE": "Den Kopf abtrennen", "ja" : "HEADの分離", "ru_RU": "Теряем голову, или detached HEAD", - "ko" : "HEAD 분리하기", - "uk": "Втрачаємо голову чи detached HEAD" + "ko" : "HEAD 분리하기", + "uk": "Втрачаємо голову чи detached HEAD", + 'vi': "Tháo đầu cái nào", + "sl_SI": "Ločevanje tvoje glave - HEAD-a", + "pl" : "Odczep swój HEAD" }, "hint": { "en_US": "Use the label (hash) on the commit for help!", "es_AR": "¡Usá la etiqueta (hash) sobre el commit para ayudarte!", + "es_ES": "¡Usa la etiqueta (hash) sobre el commit para ayudarte!", "pt_BR": "Use o identificador (hash) sobre o commit para te ajudar!", + "gl" : "¡Usa a etiqueta (hash) sobre o commit para axudarte!", "de_DE": "Benutze den Bezeichner (den Hash) des Commits.", "ja" : "コミットのラベル(hash)を使用", - "fr_FR": "Utiiser le label (identifiant) du commit pour aider !", + "fr_FR": "Utilisez le label (identifiant) du commit pour aider !", "zh_TW": "使用 commit 上的標籤(hash)來幫助你!", "zh_CN": "使用提交记录上的标签(哈希值)来指定提交记录!", "ru_RU": "Ориентируйся по идентификаторам (hash) коммитов.", "ko" : "커밋에 있는 라벨(hash)을 활용하세요!", - "uk": "Орієнтуйся по індентифікаторам (hash) комітів." + "uk": "Орієнтуйся по індентифікаторам (hash) комітів.", + "vi": "Dùng mã băm (hash) của commit để hoàn thành!", + "sl_SI": "Uporabi oznako (hash) commita za pomoč!", + "pl": "Wpisz (hash) w wiadomości commita aby uzyskać pomoc!", }, "startDialog": { "en_US": { @@ -69,9 +79,9 @@ exports.level = { "Let's see this in action. Here we will reveal HEAD before and after a commit." ], "afterMarkdowns": [ - "See! HEAD was hiding underneath our `master` branch all along." + "See! HEAD was hiding underneath our `main` branch all along." ], - "command": "git checkout C1; git checkout master; git commit; git checkout C2", + "command": "git checkout C1; git checkout main; git commit; git checkout C2", "beforeCommand": "" } }, @@ -83,7 +93,7 @@ exports.level = { "", "Detaching HEAD just means attaching it to a commit instead of a branch. This is what it looks like beforehand:", "", - "HEAD -> master -> C1", + "HEAD -> main -> C1", "" ], "afterMarkdowns": [ @@ -144,12 +154,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Veamoslo en acción. Acá vamos a ver a HEAD antes y después de un commit." + "Veámoslo en acción. Acá vamos a ver a HEAD antes y después de un commit." ], "afterMarkdowns": [ - "¡Ves! HEAD estuvo oculta bajo nuestra rama `master` todo este tiempo." + "¡Ves! HEAD estuvo oculta bajo nuestra rama `main` todo este tiempo." ], - "command": "git checkout C1; git checkout master; git commit; git checkout C2", + "command": "git checkout C1; git checkout main; git commit; git checkout C2", "beforeCommand": "" } }, @@ -161,7 +171,7 @@ exports.level = { "", "Detachear (_des-adjuntar_) HEAD simplemente significa adjuntarla a un commit en lugar de a un branch. Así es como se ve de antemano:", "", - "HEAD -> master -> C1", + "HEAD -> main -> C1", "" ], "afterMarkdowns": [ @@ -177,7 +187,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Para completar este nivel, detacheemos HEAD de `bugFix` y ataccheemosla al commit, en cambio.", + "Para completar este nivel, detacheemos HEAD de `bugFix` y atacheemosla al commit, en cambio.", "", "Especificá este commit por su hash. El hash de cada commit se muestra en el círculo que lo representa." ] @@ -185,6 +195,84 @@ exports.level = { } ] }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Moviéndote por ahí con Git", + "", + "Antes de meternos en algunas de las funcionalidades más avanzadas de git, es importante entender las distintas maneras de moverse por el árbol de commits que representa tu proyecto.", + "", + "Una vez que estés cómodo moviendote por ahí, tus poderes con los otros comandos de git ¡van a amplificarse!", + "", + "", + "", + "", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## HEAD", + "", + "Primero tenemos que hablar de \"HEAD\". HEAD es el nombre simbólico del commit sobre el que hemos hecho checkout -- es, básicamente, el commit sobre el que estás trabajando.", + "", + "HEAD siempre apunta al commit más reciente, reflejado en el árbol de commits. La mayoría de los comandos de git que hacen cambios al árbol de commits empiezan modificando HEAD.", + "", + "Normalmente HEAD apunta al nombre de una rama (como bugFix). Cuando creas un commit, el estado de bugFix se altera y este cambio es visible a través de HEAD." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Veámoslo en acción. A continuación vamos a ver a HEAD antes y después de un commit." + ], + "afterMarkdowns": [ + "¡Ves! HEAD estuvo oculta bajo nuestra rama `main` todo este tiempo." + ], + "command": "git checkout C1; git checkout main; git commit; git checkout C2", + "beforeCommand": "" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "### Detacheando HEAD", + "", + "Detachear (_des-adjuntar_) HEAD simplemente significa adjuntarla a un commit en lugar de a un branch. Así es como se ve de antemano:", + "", + "HEAD -> main -> C1", + "" + ], + "afterMarkdowns": [ + "Y así queda ahora:", + "", + "HEAD -> C1" + ], + "command": "git checkout C1", + "beforeCommand": "" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para completar este nivel, detaheemos HEAD de `bugFix` y atacheemosla al commit, en cambio.", + "", + "Especifica este commit por su hash. El hash de cada commit se muestra en el círculo que lo representa." + ] + } + } + ] + }, "pt_BR": { "childViews": [ { @@ -225,9 +313,9 @@ exports.level = { "Vejamos isto em ação. Aqui vamos mostrar o HEAD antes e depois de um commit." ], "afterMarkdowns": [ - "Veja! O HEAD estava se escondendo ao lado do nosso `master` esse tempo todo." + "Veja! O HEAD estava se escondendo ao lado do nosso `main` esse tempo todo." ], - "command": "git checkout C1; git checkout master; git commit; git checkout C2", + "command": "git checkout C1; git checkout main; git commit; git checkout C2", "beforeCommand": "" } }, @@ -239,7 +327,7 @@ exports.level = { "", "Soltar o HEAD significa anexá-lo a um commit em vez de anexá-lo a um ramo. Antes do estado solto (\"detached\"), é assim como se parece:", "", - "HEAD -> master -> C1", + "HEAD -> main -> C1", "" ], "afterMarkdowns": [ @@ -263,6 +351,84 @@ exports.level = { } ] }, + "gl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Movéndose en Git", + "", + "Antes de seguir con algunhas das funcionalidades máis avanzadas de Git, é importante entender as diferentes formas de se mover a través da árbore de commits que representa o teu proxecto.", + "", + "¡Unha vez que te sintas ben ó teu redor, os teus poderes empregando outros comandos de git serán amplificados!", + "", + "", + "", + "", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## HEAD", + "", + "Primeiro temos que falar sobre o \"commit actual\" (\"HEAD\"). HEAD é un nome simbólico para o commit atualmente ativo (o último checkout que se fixo) -- é esencialmente o commit sobre o cal estás traballando nese momento.", + "", + "O HEAD sempre apunta para o commit máis recentemente copiado sobre a árbore de traballo (arquivos do proxecto). A maioría dos comandos de git que fan algún cambio sobre a árbore de traballo empezarán movendo o HEAD.", + "", + "Normalmente o HEAD apunta para o nome dunha rama (por exemplo, bugFix). Quando fagas commit, o status do bugFix é alterado e ese cambio ocorre tamén sobre o HEAD." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Vexamos isto en acción. Aquí imos mostrar o HEAD antes e depois dun commit." + ], + "afterMarkdowns": [ + "Ves! O HEAD estivo ó lado do noso `main` todo este tempo." + ], + "command": "git checkout C1; git checkout main; git commit; git checkout C2", + "beforeCommand": "" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "### Soltando a cabeza", + "", + "Soltar o HEAD significa apuntar a un commit en vez de apuntar a unha rama. Antes do estado solo (\"detached\"), é así como aparece:", + "", + "HEAD -> main -> C1", + "" + ], + "afterMarkdowns": [ + "E agora é", + "", + "HEAD -> C1" + ], + "command": "git checkout C1", + "beforeCommand": "" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para completar este nivel, imos soltar o HEAD de `bugFix` e en vez diso apuntamos ó commit.", + "", + "Especifica o commit por medio do hash correspondente. O hash de cada commit está dentro do círculo que representa ó commit (a letra C seguida dun número)." + ] + } + } + ] + }, "fr_FR": { "childViews": [ { @@ -303,9 +469,9 @@ exports.level = { "Voyons cela en action. Ici nous allons indiquer où se situe HEAD avant et après un commit." ], "afterMarkdowns": [ - "Vous voyez ! HEAD était caché en dessous de la branche `master` tout le long." + "Vous voyez ! HEAD était caché en dessous de la branche `main` tout le long." ], - "command": "git checkout C1; git checkout master; git commit; git checkout C2", + "command": "git checkout C1; git checkout main; git commit; git checkout C2", "beforeCommand": "" } }, @@ -317,7 +483,7 @@ exports.level = { "", "Détacher HEAD signifie simplement que l'on attache HEAD à un commit au lieu d'une branche. Voilà à quoi cela ressemble actuellement :", "", - "HEAD -> master -> C1", + "HEAD -> main -> C1", "" ], "afterMarkdowns": [ @@ -349,7 +515,7 @@ exports.level = { "markdowns": [ "## Navigation durch Git", "", - "Bevor wir uns einige fortgeschrittene Konzepte in Git ansehen ist es wichtig, verschiedene Wege zum Navigieren durch den Commit-Baum, der das Projekt enthält, zu kennen.", + "Bevor wir uns einige fortgeschrittene Konzepte in Git ansehen, ist es wichtig, verschiedene Wege zum Navigieren durch den Commit-Baum, der das Projekt enthält, zu kennen.", "", "Sobald du das drauf hast, vergrößern sich deine Möglichkeiten in allen anderen Git-Befehlen.", "", @@ -368,7 +534,7 @@ exports.level = { "", "Erst mal müssen wir über `HEAD` reden. `HEAD` ist ein Alias für den Commit, der gerade ausgecheckt ist -- es ist im Prinzip der Commit, an den du deinen nächsten Commit hängst.", "", - "`HEAD` zeigt immer auf den neuesten Commit. Die meisten Git-Befehle, die den Baum verändern, fangen damit an dass sie `HEAD` verschieben.", + "`HEAD` zeigt immer auf den neuesten Commit. Die meisten Git-Befehle, die den Baum verändern, fangen damit an, dass sie `HEAD` verschieben.", "", "Normalerweise zeigt `HEAD` auf einen Branch-Namen (z.B. `bugFix`). Wenn du einen Commit machst, wird `bugFix` auf diesen Commit geschoben, und `HEAD` (da es auf `bugFix` zeigt) automatisch auch." ] @@ -381,9 +547,9 @@ exports.level = { "Schauen wir uns das mal in Aktion an. Wir werden hier `HEAD` vor und nach dem Commit anzeigen." ], "afterMarkdowns": [ - "Siehst du? `HEAD` war die ganze Zeit unter `master` versteckt." + "Siehst du? `HEAD` war die ganze Zeit unter `main` versteckt." ], - "command": "git checkout C1; git checkout master; git commit; git checkout C2", + "command": "git checkout C1; git checkout main; git commit; git checkout C2", "beforeCommand": "" } }, @@ -395,7 +561,7 @@ exports.level = { "", "`HEAD` abzukoppeln bedeutet, es direkt an einen bestimmten Commit zu hängen, anstatt an einen Branch. Wir gelangen dadurch in den \"detached HEAD state\". So sieht's vorher aus:", "", - "`HEAD` -> `master` -> `C1`", + "`HEAD` -> `main` -> `C1`", "" ], "afterMarkdowns": [ @@ -455,12 +621,12 @@ exports.level = { "下面咱们通过实际操作看一下。我们将会观察提交前后 HEAD 的位置。" ], "afterMarkdowns": [ - "看到了吗? HEAD 指向了 `master`,随着提交向前移动。", + "看到了吗? HEAD 指向了 `main`,随着提交向前移动。", "", "(译者注:实际这些命令并不是真的在查看 HEAD 指向,看下一屏就了解了。如果想看 HEAD 指向,可以通过 `cat .git/HEAD` 查看,", "如果 HEAD 指向的是一个引用,还可以用 `git symbolic-ref HEAD` 查看它的指向。但是该程序不支持这两个命令)" ], - "command": "git checkout C1; git checkout master; git commit; git checkout C2", + "command": "git checkout C1; git checkout main; git commit; git checkout C2", "beforeCommand": "" } }, @@ -472,9 +638,9 @@ exports.level = { "", "分离的 HEAD 就是让其指向了某个具体的提交记录而不是分支名。在命令执行之前的状态如下所示: ", "", - "HEAD -> master -> C1", + "HEAD -> main -> C1", "", - "HEAD 指向 master, master 指向 C1" + "HEAD 指向 main, main 指向 C1" ], "afterMarkdowns": [ "现在变成了", @@ -533,9 +699,9 @@ exports.level = { "在實際的例子中。我們將會觀察 commit 前後 HEAD 的位置。" ], "afterMarkdowns": [ - "看吧!HEAD 一直藏在 `master` 分支的後面。" + "看吧!HEAD 一直藏在 `main` 分支的後面。" ], - "command": "git checkout C1; git checkout master; git commit; git checkout C2", + "command": "git checkout C1; git checkout main; git commit; git checkout C2", "beforeCommand": "" } }, @@ -547,7 +713,7 @@ exports.level = { "", "分離 HEAD 就是讓其指向一個 commit 而不是 branch 的名稱。這是指令執行之前的樣子:", "", - "HEAD -> master -> C1", + "HEAD -> main -> C1", "" ], "afterMarkdowns": [ @@ -611,9 +777,9 @@ exports.level = { "実際の動作を見てみましょう。ここでは、コミットの前と後のHEADの状態を確認します。" ], "afterMarkdowns": [ - "ほら、HEADが元から`master`ブランチの下に隠れていたんですね!" + "ほら、HEADが元から`main`ブランチの下に隠れていたんですね!" ], - "command": "git checkout C1; git checkout master; git commit; git checkout C2", + "command": "git checkout C1; git checkout main; git commit; git checkout C2", "beforeCommand": "" } }, @@ -625,7 +791,7 @@ exports.level = { "", "HEADの分離(detached HEAD)とは単に、ブランチではなく特定のコミットにHEADを紐づけることです。実行前の状態は次のようです:", "", - "HEAD -> master -> C1", + "HEAD -> main -> C1", "" ], "afterMarkdowns": [ @@ -689,9 +855,9 @@ exports.level = { "Посмотрим, как это работает. Обратите внимание на то, где находится HEAD до и после коммита." ], "afterMarkdowns": [ - "Вот! HEAD всё это время скрывался за веткой `master`." + "Вот! HEAD всё это время скрывался за веткой `main`." ], - "command": "git checkout C1; git checkout master; git commit; git checkout C2", + "command": "git checkout C1; git checkout main; git commit; git checkout C2", "beforeCommand": "" } }, @@ -703,7 +869,7 @@ exports.level = { "", "Отделение (detaching) HEAD означает лишь присвоение его не ветке, а конкретному коммиту. Посмотрим, что было до отделения:", "", - "HEAD -> master -> C1", + "HEAD -> main -> C1", "" ], "afterMarkdowns": [ @@ -727,7 +893,7 @@ exports.level = { } ] }, - "ko": { + "ko": { "childViews": [ { "type": "ModalAlert", @@ -767,9 +933,9 @@ exports.level = { "직접 확인해 봅시다. 여기서 우리는 보이지 않던 HEAD를 커밋전, 후에 드러낼 것입니다." ], "afterMarkdowns": [ - "보세요! HEAD가 `master`브랜치 아래에 숨어 있던 거군요." + "보세요! HEAD가 `main`브랜치 아래에 숨어 있던 거군요." ], - "command": "git checkout C1; git checkout master; git commit; git checkout C2", + "command": "git checkout C1; git checkout main; git commit; git checkout C2", "beforeCommand": "" } }, @@ -781,7 +947,7 @@ exports.level = { "", "HEAD를 분리한다는 것은 HEAD를 브랜치 대신 커밋에 붙이는 것을 의미합니다. 명령을 사용하기 전의 모습은 다음과 같습니다:", "", - "HEAD -> master -> C1", + "HEAD -> main -> C1", "" ], "afterMarkdowns": [ @@ -845,9 +1011,9 @@ exports.level = { "Розберемось з цим на практиці. Зараз ми перевіримо HEAD до та після коміту." ], "afterMarkdowns": [ - "Ти диви! HEAD весь цей час ховався за гілкою `master`." + "Ти диви! HEAD весь цей час ховався за гілкою `main`." ], - "command": "git checkout C1; git checkout master; git commit; git checkout C2", + "command": "git checkout C1; git checkout main; git commit; git checkout C2", "beforeCommand": "" } }, @@ -859,7 +1025,7 @@ exports.level = { "", "Detached HEAD (відокремлена голова) просто означає що HEAD посилається на коміт, а не на якусь гілку. Ось як це виглядає спочатку:", "", - "HEAD -> master -> C1", + "HEAD -> main -> C1", "" ], "afterMarkdowns": [ @@ -882,6 +1048,240 @@ exports.level = { } } ] + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Dịch chuyển trong Git", + "", + "Trước khi học thêm vài chức năng nâng cao trong Git, ta cần phải biết cách dịch chuyển qua lại các commit có trong kho chứa.", + "", + "Một khi bạn đã thành thao với chuyển dịch, khả năng sử dụng các lệnh git của bạn đã được nâng cao!", + "", + "", + "", + "", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## HEAD", + "", + "Đầu tiên hãy bàn về 'HEAD'. HEAD là cái tên biểu tượng cho commit iện tại đang được trỏ đến -- về căn bản nó là commit mà bạn đang làm việc.", + "", + "HEAD luôn luôn trỏ đến commit gần nhất được phản ánh trong cây làm việc. Hầu hết các lệnh git mà làm thay đổi nội dung cây làm việc thường bắt đầu với HEAD.", + "", + "Bình thường HEAD thì trỏ tới tên nhánh (ví dụ bugFix). Khi bạn commit, thì trạng thái của bugFix được thay đổi và thay đổi này được trông thấy thông qua HEAD." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Xem thử thực tế nào. Ở đây ta sẽ bộc lộ HEAD trước và sau khi commit." + ], + "afterMarkdowns": [ + "Thấy chứ? HEAD đã ẩn dưới nhánh `main` suốt." + ], + "command": "git checkout C1; git checkout main; git commit; git checkout C2", + "beforeCommand": "" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "### Tháo HEAD", + "", + "Tháo HEAD đơng giản nghĩa là dán nó vào một commit thay vì một nhánh. Lúc trước thì nó trông như thế này:", + "", + "HEAD -> main -> C1", + "" + ], + "afterMarkdowns": [ + "Và bây giờ thì nó thế này", + "", + "HEAD -> C1" + ], + "command": "git checkout C1", + "beforeCommand": "" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Để hoàn thành cấp độ này, hãy tháo HEAD khỏi `bugFix` thay vì đó hãy dán nó vào commit.", + "", + "Chỉ rõ commit bằng mã băm (hash) của nó. Mã băm của mỗi commit nằm trong trong vòng tròn biểu thị commit đó." + ] + } + } + ] + }, + "sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Premikanje po Gitu", + "", + "Preden se lotimo nekaj naprednejših funkcij Gita je pomembno, da razumemo različne načine premikanja po drevesu commitov, ki predstavljajo tvoj projekt.", + "", + "Ko ti je enkrat premikanje po drevesu domače, bodo tvoje sposobnosti z ostalimi git ukazi še močnejše!", + "", + "", + "", + "", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## HEAD", + "", + "Najprej moramo spozanti \"HEAD\". HEAD (glava) je simbolično ime za trenutno checkoutan commit -- v bistvu povemo na katerem commitom bomo nadaljevali.", + "", + "HEAD vedno kaže na zadnji commit na trenutnem drevesu. Večina git ukazov, ki spreminjajo to delovno drevo, bo začelo s spremembo HEAD-a.", + "", + "Ponavadi HEAD kaže na ime brancha (npr. bugFix). Ko commitaš, je stanje bugFix spremenjeno in ta sprememba je opazna tudi skozi HEAD." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Poglejmo to v akciji. Sedaj bomo razkrili HEAD pred in po commitu." + ], + "afterMarkdowns": [ + "Evo! HEAD se je vseskozi skrival pod našim `main` branchom." + ], + "command": "git checkout C1; git checkout main; git commit; git checkout C2", + "beforeCommand": "" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "### Ločevanje HEAD-a", + "", + "Ločevanje HEAD-a pomeni samo, da ga namestno na branch sedaj pripnemo na commit. Tako je izgledalo prej:", + "", + "HEAD -> main -> C1", + "" + ], + "afterMarkdowns": [ + "Sedaj pa je takole:", + "", + "HEAD -> C1" + ], + "command": "git checkout C1", + "beforeCommand": "" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Za dokončanje te stopnje odstranimo HEAD iz `bugFix` in ga pritrdimo raje na commit.", + "", + "Določi ta commit z njegovim hash-om. Hash za vsak commit je predstavljen v krogu, ki predstavlja commit." + ] + } + } + ] + }, + "pl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Poruszanie się w Git", + "", + "Zanim przejdziemy do niektórych z bardziej zaawansowanych funkcji Gita, ważne jest, aby zrozumieć różne sposoby poruszania się po drzewie commitów, które reprezentują twój projekt.", + "", + "Kiedy będziesz już czuć się swobodnie, twoje moce z innymi komendami gitowymi zostaną wzmocnione!", + "", + "", + "", + "", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## HEAD", + "", + "Najpierw musimy porozmawiać o \"HEAD\". HEAD to symboliczna nazwa dla aktualnie zcheckout'owanego commitu - jest to zasadniczo ostatni commit nad, którym pracowałeś.", + "", + "HEAD zawsze wskazuje na najnowszy commit, który jest odzwierciedlony w drzewie zmian. Większość poleceń git, które wprowadzają zmiany w drzewie, zaczyna się od zmiany HEAD'a.", + "", + "Normalnie HEAD wskazuje na nazwę gałęzi (jak np. `bugFix`). Kiedy commitujesz zmiany, status gałęzi `bugFix` się zmienia i zmiana ta jest widoczna właśnie poprzez przemieszczenie się HEAD'a." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Sprawdźmy to w akcji. Pokażemy HEAD przed i po commicie." + ], + "afterMarkdowns": [ + "Zobacz! HEAD przez cały czas ukrywał się pod naszą gałęzią `main`." + ], + "command": "git checkout C1; git checkout main; git commit; git checkout C2", + "beforeCommand": "" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "### Odłączanie HEAD'a", + "", + "Odłączenie HEAD'a oznacza po prostu dołączenie go do commita, a nie gałęzi. Tak to wyglądało przed:", + "", + "HEAD -> main -> C1", + "" + ], + "afterMarkdowns": [ + "A tak po:", + "", + "HEAD -> C1" + ], + "command": "git checkout C1", + "beforeCommand": "" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Aby ukończyć ten poziom, odłącz HEAD od gałęzi `bugFix` i dołącz go do commita.", + "", + "Możesz wybrać konkretnego commita posługując się jego haszem. Hasz każdego commita jest wyświetlany na okręgu, który go reprezentuje." + ] + } + } + ] } } }; diff --git a/src/levels/rampup/interactiveRebase.js b/src/levels/rampup/interactiveRebase.js index ed3aaf1e..2ae6cd1a 100644 --- a/src/levels/rampup/interactiveRebase.js +++ b/src/levels/rampup/interactiveRebase.js @@ -1,4 +1,4 @@ -exports.level = { +exports.level = { "goalTreeString": "%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C4%27%22%2C%22id%22%3A%22master%22%7D%2C%22overHere%22%3A%7B%22target%22%3A%22C1%22%2C%22id%22%3A%22overHere%22%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C4%22%3A%7B%22parents%22%3A%5B%22C3%22%5D%2C%22id%22%3A%22C4%22%7D%2C%22C5%22%3A%7B%22parents%22%3A%5B%22C4%22%5D%2C%22id%22%3A%22C5%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C3%27%22%7D%2C%22C5%27%22%3A%7B%22parents%22%3A%5B%22C3%27%22%5D%2C%22id%22%3A%22C5%27%22%7D%2C%22C4%27%22%3A%7B%22parents%22%3A%5B%22C5%27%22%5D%2C%22id%22%3A%22C4%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%7D", "solutionCommand": "git rebase -i overHere --solution-ordering C3,C5,C4", "compareOnlyMasterHashAgnostic": true, @@ -9,20 +9,27 @@ "hint": { "en_US": "you can use either branches or relative refs (HEAD~) to specify the rebase target", "es_AR": "podés usar tanto ramas como referencias relativas (HEAD~) para especificar el objetivo del rebase", + "es_ES": "puedes usar tanto ramas como referencias relativas (HEAD~) para especificar el objetivo del rebase", "pt_BR": "Você pode usar ou ramos ou referências relativas (HEAD~) para especificar o alvo do rebase", + "gl" : "Podes usar ramas ou referencias relativas (HEAD~) para especificar o obxectivo do rebase", "de_DE": "Du kannst entweder Branches oder relative Ref-Angaben (z.B. HEAD~) benutzen, um das Ziel des Rebase anzugeben.", - "fr_FR": "Vous pouvez utiliser soit les branches, soit les références relatives (HEAD~) pour spéficier la cible à rebaser", + "fr_FR": "Vous pouvez utiliser soit les branches, soit les références relatives (HEAD~) pour spécifier la cible à rebaser", "zh_CN": "branch 或者是相对位置(HEAD~)都可以用來指定 rebase 的目标", "zh_TW": "你可以指定 branch 或者是相對位置(HEAD~)來表示 rebase 的目標", "ru_RU": "Можно использовать либо ветки, либо относительные ссылки (HEAD~), чтобы указать цель для Rebase", "ja" : "リベースする対象の指定には、ブランチ名や相対リファレンス(HEAD~)が使えます", "ko" : "리베이스할 타겟으로 브랜치나 상대 참조(HEAD~)를 사용할 수 있습니다", - "uk" : "ти можеш використовувати гілки чи відносні посилання (HEAD~) щоб вказувати ціль для rebase" + "uk" : "ти можеш використовувати гілки чи відносні посилання (HEAD~) щоб вказувати ціль для rebase", + "vi": "bạn có thể sử dụng tham chiếu tương đối (HEAD~) hoặc nhánh để chỉ định mục tiêu rebase", + "sl_SI": "Uporabiš lahko bilokateri branch ali relativno referenco (HEAD~), da določiš cilj za rebase.", + "pl": "Możesz użyć gałęzi lub referencji względnych (HEAD~), aby określić cel rebase'a" }, "name": { "en_US": "Interactive Rebase Intro", "es_AR": "Introducción al rebase interactivo", + "es_ES": "Introducción al rebase interactivo", "pt_BR": "Introdução ao rebase interativo", + "gl" : "Introducción ó rebase interativo", "de_DE": "Einführung Interactive Rebase", "ja" : "インタラクティブrebase入門", "fr_FR": "Introduction à rebase", @@ -30,7 +37,10 @@ "zh_TW": "介紹互動式的 rebase", "ru_RU": "Введение в интерактивный Rebase", "ko" : "인터랙티브 리베이스 소개", - "uk" : "Знайомство з інтерактивним rebase" + "uk" : "Знайомство з інтерактивним rebase", + "vi" : "Giới thiệu về tương tác rebase", + "sl_SI": "Interaktivni uvod v Rebase", + "pl": "Interaktywne wprowadzenie do Rebase'a", }, "startDialog": { "en_US": { @@ -65,11 +75,14 @@ "type": "ModalAlert", "options": { "markdowns": [ - "When the interactive rebase dialog opens, you have the ability to do 3 things:", + "When the interactive rebase dialog opens, you have the ability to do two things in our educational application:", "", - "* You can reorder commits simply by changing their order in the UI (in our window this means dragging and dropping with the mouse).", - "* You can choose to completely omit some commits. This is designated by `pick` -- toggling `pick` off means you want to drop the commit.", - "* Lastly, you can squash commits. Unfortunately our levels don't support this for a few logistical reasons, so I'll skip over the details of this. Long story short, though -- it allows you to combine commits.", + "* You can reorder commits simply by changing their order in the UI (via dragging and dropping with the mouse).", + "* You can choose to keep all commits or drop specific ones. When the dialog opens, each commit is set to be included by the `pick` " + + "button next to it being active. To drop a commit, toggle off its `pick` button.", + "", + "*It is worth mentioning that in the real git interactive rebase you can do many more things like squashing (combining) commits, " + + "amending commit messages, and even editing the commits themselves. For our purposes though we will focus on these two operations above.*", "", "Great! Let's see an example." ] @@ -82,7 +95,7 @@ "When you hit the button, an interactive rebase window will appear. Reorder some commits around (or feel free to unpick some) and see the result!" ], "afterMarkdowns": [ - "Boom! Git copied down commits in the exact same way you specified through the UI" + "Boom! Git copied down commits in the exact same way you specified through the UI." ], "command": "git rebase -i HEAD~4 --aboveAll", "beforeCommand": "git commit; git commit; git commit; git commit" @@ -108,7 +121,7 @@ "", "Git cherry-pick est pratique quand vous savez exactement quels commits vous voulez (_et_ que vous connaissez leurs identifiants) -- il est difficile de battre la simplicité qu'il procure.", "", - "Mais que faire quand vous ne connaissez pas les identifiants des commits ? Heureusement git a pensé à vous dans pour ce cas-là ! Nous pouvons utiliser un rebase interactif pour cela -- c'est la meilleure façon de reconsidérer une série de commits que vous vous apprêtez à rebaser.", + "Mais que faire quand vous ne connaissez pas les identifiants des commits ? Heureusement git a pensé à vous pour ce cas-là ! Nous pouvons utiliser un rebase interactif pour cela -- c'est la meilleure façon de reconsidérer une série de commits que vous vous apprêtez à rebaser.", "", "Allons un peu plus dans les détails ..." ] @@ -236,7 +249,7 @@ "markdowns": [ "## 交互式的 rebase", "", - "当你你知道你所需要的提交记录(**并且**还知道这些提交记录的哈希值)时, 用 cherry-pick 再好不过了 —— 没有比这更简单的方式了。", + "当你知道你所需要的提交记录(**并且**还知道这些提交记录的哈希值)时, 用 cherry-pick 再好不过了 —— 没有比这更简单的方式了。", "", "但是如果你不清楚你想要的提交记录的哈希值呢? 幸好 Git 帮你想到了这一点, 我们可以利用交互式的 rebase —— 如果你想从一系列的提交记录中找到想要的记录, 这就是最好的方法了", "", @@ -317,7 +330,7 @@ "", "Si incluís esta opción, git abrirá una UI para mostrarte qué commits están a punto de ser copiados sobre el objetivo del rebase. También muestra sus hashes y mensajes, que ayuda mucho para saber qué es cada commit.", "", - "Para el git \"de verdad\", la UI signfica abrir un archivo en un editor de textos como `vim`. Para nuestro propósito, hice una pequeña interfaz que se comporta de ese mismo modo." + "Para el git \"de verdad\", la UI significa abrir un archivo en un editor de textos como `vim`. Para nuestro propósito, hice una pequeña interfaz que se comporta de ese mismo modo." ] } }, @@ -342,7 +355,7 @@ "Cuando apretes el botón, va a aparecer una ventana de rebase interactivo. Reordená los commits (sentite libre de ignorar alguno, también) ¡y mirá el resultado!" ], "afterMarkdowns": [ - "¡Boom! Git copió los commits exactamente de la misma manera que lo especificaste en la UI" + "¡Boom! Git copió los commits exactamente de la misma manera que lo especificaste en la UI." ], "command": "git rebase -i HEAD~4 --aboveAll", "beforeCommand": "git commit; git commit; git commit; git commit" @@ -358,6 +371,71 @@ } ] }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## git rebase interactivo", + "", + "git cherry-pick es genial cuando sabes qué commits quieres (_y_ sabes sus hashes) -- es dificil superar la simpleza que provee.", + "", + "Pero ¿qué pasa cuando no sabes qué commits quieres? Por suerte ¡git te cubre en esta situación, también! Podemos usar el rebase interactivo para esto -- es la mejor manera de revisar una serie de commits que estás a punto de rebasear.", + "", + "Entremos en los detalles..." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Todo rebase interactivo significa usar el comando `rebase` con la opción `-i`.", + "", + "Si incluyes esta opción, git abrirá una UI para mostrarte qué commits están a punto de ser copiados sobre el objetivo del rebase. También muestra sus hashes y mensajes, que ayuda mucho para saber qué es cada commit.", + "", + "Para el git \"de verdad\", la UI signfica abrir un archivo en un editor de textos como `vim`. Para nuestro propósito, hice una pequeña interfaz que se comporta de ese mismo modo." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Cuando el diálogo de rebase interactivo se abre, tienes la capacidad de hacer 3 cosas:", + "", + "* Puedes reordenar los commits con solamente cambiar su orden en la UI (en nuestra ventana, eso significa hacer drag & drop con el mouse).", + "* Puedes elegir ignorar completamente algunos commits. Esto se designa con `pick` -- no hacerle `pick` a algún commit significa que quieres ignorarlo.", + "* Finalmente, puedes _squashear_ commits. Desafortunadamente, nuestros niveles no soportan esto por cuestiones logísticas, por lo que voy a ahorrarte los detalles. Resumiendo, te permite combinar varios commits en uno solo.", + "", + "¡Genial! Veamos un ejemplo." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Cuando aprietes el botón, va a aparecer una ventana de rebase interactivo. Reordena los commits (siéntete libre de ignorar alguno, también) ¡y observa el resultado!" + ], + "afterMarkdowns": [ + "¡Zas! Git copió los commits exactamente de la misma manera que lo especificaste en la UI." + ], + "command": "git rebase -i HEAD~4 --aboveAll", + "beforeCommand": "git commit; git commit; git commit; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para completar el nivel, haz un rebase interactivo y alcanza el orden que se muestra en la visualización objetivo. Recuerda que siempre puedes hacer `undo` y `reset` para arreglar errores :D" + ] + } + } + ] + }, "pt_BR": { "childViews": [ { @@ -407,7 +485,7 @@ "Quando você clicar o botão, uma janela de rebase interativo se abrirá. Reordene alguns commits da forma como você preferir (ou sinta-se livre para desmarcar o `pick` de alguns) e veja o resultado!" ], "afterMarkdowns": [ - "Boom! O Git copiou alguns commits exatamente da mesma forma que você os especificou na janela" + "Boom! O Git copiou alguns commits exatamente da mesma forma que você os especificou na janela." ], "command": "git rebase -i HEAD~4 --aboveAll", "beforeCommand": "git commit; git commit; git commit; git commit" @@ -423,6 +501,71 @@ } ] }, + "gl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Rebase Interativo en Git", + "", + "Empregar cherry-pick é xenial cando coñeces qué commits queres (_e_ coñeces os seus códigos hash) -- é difícil mellorar a súa simplicidade.", + "", + "Pero ¿qué pasa cando non sabes qué commits son os que queres? Por sorte, ¡git cúbrete nesta situación tamén! Podemos empregar o rebase interactivo para esto -- é a mellor forma de revisar unha serie de commits que estás a rebasar.", + "", + "Mergullémonos nos detalles..." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "O rebase interativo é o comando `rebase` coa opción `-i`.", + "", + "Se ti inclúes esta opción, o git abrirá unha interfaz para mostrar qué commits están hábiles para ser copiados sobre o obxectivo do rebase. Tamén amosa os seus códigos hash e mensaxes dos commits, o cal axuda moito para saber qué é cada commit.", + "", + "En git \"de verdade\", a interfaz significa abrir un arquivo de texto nun editor (por exemplo `vim`). Para os nosos propósitos, aquí aparecerá unha pequena ventá que se comporta do mesmo xeito." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Cando a xanela de rebase interativo abra, poderás facer 3 cousas distintas:", + "", + "* Podes reordenar os commits simplemente cambiando a súa orde na interface (na nosa ventá significa arrastrar e soltar os commits).", + "* Podes escoller a opción de omitir algúns commits. Para iso, pincha no botón `pick` -- deixar o `pick` desligado significa que queres descartar o commit.", + "* Ademáis, ti podes \"esmagar\" (fazer squash) nos commits. Tristemente, este tutorial non será capaz de cubrir esa funcionalidade por algúns motivos loxísticos, entón imos pulir algúns detalles ó respecto. Resumindo, o squash permite combinar commits.", + "", + "¡Xenial! Vexamos un exemplo." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Cando pinches o botón, unha ventá de rebase interativo abrirase. Reordena algúns commits da forma que ti prefieras (ou se o prefires desmarca o `pick` de algúns) e mira o seu resultado!" + ], + "afterMarkdowns": [ + "¡Veña! Git copiou algúns commits exatamente da mesma forma que o indicaches na ventá." + ], + "command": "git rebase -i HEAD~4 --aboveAll", + "beforeCommand": "git commit; git commit; git commit; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para finalizar este nivel, fai un rebase interativo e obteñaa a orde amosada na visualización do obxectivo. Lembra que podes usar os comandos `undo` ou `reset` para correxir erros :D" + ] + } + } + ] + }, "de_DE": { "childViews": [ { @@ -431,9 +574,9 @@ "markdowns": [ "## Interaktiver Rebase", "", - "Cherry-pick ist großartig wenn du genau weißt, welche Commits du willst (_und_ ihre jeweiligen Hashes kennst) -- es ist dann schwer an Einfachheit zu überbieten.", + "Cherry-pick ist großartig, wenn du genau weißt, welche Commits du willst (_und_ ihre jeweiligen Hashes kennst) -- es ist dann schwer an Einfachheit zu überbieten.", "", - "Aber wie sieht es aus, wenn du die Commits nicht genau kennst, die du brauchst? Zum Glück bietet Git auch dafür eine Lösung an. Das können wir mit interaktivem Rebase machen -- die beste Art sich eine Serie von Commits in einem Rebase genau anzusehen.", + "Aber wie sieht es aus, wenn du die benötigten Commits nicht genau kennst? Zum Glück bietet Git auch dafür eine Lösung an. Das können wir mit interaktivem Rebase machen -- die beste Art sich eine Serie von Commits in einem Rebase genau anzusehen.", "", "Schauen wir uns die Details an ..." ] @@ -447,7 +590,7 @@ "", "Wenn du das machst, zeigt Git dir jeden einzelnen Commit, der durch den Rebase kopiert werden würde. Es zeigt dir die Hashes und Kommentare, was gut ist um einen Überblick zu bekommen.", "", - "In echtem Git besteht dieser Dialog daraus, die Commits in einem Text-Editor angezeigt zu bekommen. Für unsere Zwecke hab ich ein kleines Dialog-Fenster gebaut, dass sich ähnlich verhält." + "Im \"echten\" Git werden die Commits in einem Text-Editor angezeigt (z.B. in `vim`). Für unsere Zwecke habe ich ein kleines Dialog-Fenster gebaut, das sich ähnlich verhält." ] } }, @@ -458,8 +601,8 @@ "Wenn sich der Dialog für den interaktiven Rebase öffnet, kannst du drei Dinge tun:", "", "* Du kannst die Reihenfolge der Commits durch Ziehen und Ablegen ändern.", - "* Du kannst Git sagen, einen Commit beim Rebase zu ignorieren -- im Dialog durch die Schaltfläche `pick` dargestellt.", - "* Außerdem kannst du Commit zusammenfassen (squash). Leider wird das hier nicht unterstützt, aber in echtem Git fasst es Commits zu einem zusammen.", + "* Du kannst einen Commit beim Rebase ignorieren, indem du im Dialog auf die Schaltfläche `omit` klickst. Du kannst einen Commit wieder aufnehmen, indem du auf `pick` klickst.", + "* Außerdem kannst du Commits zusammenfassen (squash). Leider wird das hier nicht unterstützt, aber im echten Git fasst es Commits zu einem zusammen.", "", "Super! Schauen wir uns ein Beispiel an." ] @@ -469,7 +612,7 @@ "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Wenn du die Schaltfläche anklickst wird sich der Rebase-Dialog öffnen. Veränder die Reihenfolge der Commits oder klick bei einigen auf `pick` und schau dir das Ergebnis an." + "Wenn du die Schaltfläche anklickst, wird sich der Rebase-Dialog öffnen. Verändere die Reihenfolge der Commits oder klicke bei einigen auf `pick` bzw. `omit` und schaue dir das Ergebnis an." ], "afterMarkdowns": [ "Bämm! Git hat die Commits genau so kopiert, wie du es ausgewählt hast." @@ -482,7 +625,7 @@ "type": "ModalAlert", "options": { "markdowns": [ - "Um dieses Level zu schaffen mach einen interaktiven Rebase, um genau die Reihenfolge zu erzeugen die im Ziel-Baum angezeigt wird. Denk daran, dass du jederzeit mit `undo` oder `reset` Fehler rückgängig machen kannst. :D" + "Um dieses Level zu schaffen mach einen interaktiven Rebase, um genau die Reihenfolge zu erzeugen, die im Ziel-Baum angezeigt wird. Denk daran, dass du jederzeit mit `undo` oder `reset` Fehler rückgängig machen kannst. :D" ] } } @@ -618,7 +761,7 @@ } ] }, - "ko": { + "ko": { "childViews": [ { "type": "ModalAlert", @@ -642,7 +785,7 @@ "", "이 옵션을 추가하면, git은 리베이스의 목적지가 되는 곳 아래에 복사될 커밋들을 보여주는 UI를 띄울것 입니다. 각 커밋을 구분할 수 있는 각각의 해시들과 메시지도 보여줍니다.", "", - "\"실제\"git 에서는 UI창을 띄우는것 대신에 `vim`과 같은 텍스트 편집기에서 파일을 엽니다. 저희는 배우는것이 목적이기에 같은 역할을 하는 작은 대화창을 만들어서 대신했습니다." + "\"실제\" git 에서는 UI창을 띄우는것 대신에 `vim`과 같은 텍스트 편집기에서 파일을 엽니다. 저희는 배우는 것이 목적이기에 같은 역할을 하는 작은 대화창을 만들어서 대신했습니다." ] } }, @@ -664,7 +807,7 @@ "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "버튼을 누르면 인터렉티브 리베이스 대화창이 뜰것 입니다. 커밋들의 순서를 바꿔보고(커밋을 빼 봐도 됩니다) 결과를 확인해봅시다!" + "버튼을 누르면 인터렉티브 리베이스 대화창이 뜰 것 입니다. 커밋들의 순서를 바꿔보고(커밋을 빼 봐도 됩니다) 결과를 확인해봅시다!" ], "afterMarkdowns": [ "Boom! Git이 UI를 통해 명시한 그대로 커밋들을 복사했습니다." @@ -732,7 +875,7 @@ "Коли ти натиснеш кнопку, відкриється вікно інтерактивного rebase. Перестав якісь коміти (можеш пропустити якісь якщо хочеш), і подивись що вийде!" ], "afterMarkdowns": [ - "Ка-бум! Git cкопіював коміти відповідно до того що було вказано в UI" + "Ка-бум! Git cкопіював коміти відповідно до того що було вказано в UI." ], "command": "git rebase -i HEAD~4 --aboveAll", "beforeCommand": "git commit; git commit; git commit; git commit" @@ -747,6 +890,202 @@ } } ] - } + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Rebase Tương tác", + "", + "Khi bạn biết rõ mình muốn những commit nào (và mã băm tương ứng của chúng) thì Git cherry-pick là công cụ tuyệt vời -- nó đơn giản đến bất ngờ.", + "", + "Nhưng mà lỡ như bạn không biết mình cần commit nào thì sao? May mà git cũng có công cụ cho việc này! Ta có thể dùng rebase tương tác cho việc này -- đó là cách tốt nhất để cân nhắc lựa chọn các commit mà bạn muốn rebase.", + "", + "Hãy đi sâu vào chi tiết nào..." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Rebase tương tác nghĩa là dùng lệnh `rebase` với tùy chọn `-i`.", + "", + "Nếu lệnh của bạn có bao hàm tùy chọn này, git sẽ mở một giao diện người dùng để cho bạn biết những commit nào sẽ được sao chép xuống dưới mục tiêu rebase. Nó cũng đồng thời thể hiện mã băm và thông điệp của commit, điều này là tuyệt vời bởi nhờ đó ta có thể phân biệt được chúng.", + "", + "Với git \"thật\", cửa sổ UI (giao diện người dùng) sẽ được mở thông qua một tệp nhờ công cụ chỉnh sửa văn bản như là `vim`. Vì mục đích học tập, tôi đã xây dựng một cửa sổ hội thoại nhỏ mà nó hành xử cũng tương tự như vậy." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Khi hội thoại tương tác rebase bật lên, bạn có thể làm được 3 điều:", + "", + "* Bạn có thể sắp xếp lại commit một cách đơn giản thông qua UI (bạn có thể làm điều này bằng cách kéo thả trên công cụ của chúng tôi).", + "* Bạn có thẻ bỏ qua một vài commit. Điều này được thể hiện qua nút `pick` -- tắt nút `pick` nghĩa là bạn bỏ qua commit đó.", + "* Cuối cùng, bạn có thể nén các commit. Đáng tiếc là trình độ của chúng tôi chưa hỗ trợ được chức năng này do vài vấn đề logic, cho nên tôi sẽ bỏ qua phần này. Nói dơn giản thì -- nó cho phép bạn kết hợp các commit.", + "", + "Tuyệt! Cùng xem qua một ví dụ nào." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Khi bạn bấm nút, một cửa sổ tương tác rebase sẽ xuất hiện. Sắp xếp lại một vài commit (hoặc thậm chí bỏ qua một vài cái) và xem thử kết quả!" + ], + "afterMarkdowns": [ + "BÙÙM! Git sao chép chính xác các commit mà bạn chọn thông qua UI." + ], + "command": "git rebase -i HEAD~4 --aboveAll", + "beforeCommand": "git commit; git commit; git commit; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Để hoàn thành cấp độ này, do an interactive rebase and achieve the order shown in the goal visualization. Remember you can always `undo` or `reset` to fix mistakes :D" + ] + } + } + ] + }, + "sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Interaktivni Rebase", + "", + "Git cherry-pick je odličen način, ko veš katere commite bi rad (in poznaš njihove hashe) -- težko je premagati njegovo enostavnost.", + "", + "Ampak kaj pa situacija, ko ne veš katere commite želiš? K sreči ima git pokrito tudi to! Uporabimo lahko interaktivni rebase -- gre za najboljši način za pregled commitov, ki jih želiš rebaseati.", + "", + "Spustimo se v podrobnosti ..." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Vse kar interaktvini rebase pomeni je, da uporabimo `rebase` ukaz z opcijo `-i`.", + "", + "Če vključiš to opcijo, bo git odprl okno, da ti pokaže, kateri commiti bodo skopirani pod naš ciljni commit rebaseanja. Prav tako pokaže tudi njihove hashe in sporočila, kar je super za razumevanje kaj je kaj.", + "", + "Za \"pravi\" git, odpiranje okna pomeni odpiranje datoteke v urejevalniku kot je `vim`. Za naš namen sem zgradil majhno okno, ki se obnaša enako." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Ko se odpre okno za interaktivno rebaseanje, imaš možnost narediti 3 stvari:", + "", + "* Enostavno lahko preurediš commite v vrstni red, ki ga želiš (v našem oknu to dosežeš kar s klikom in vlečenjem miške).", + "* Odločiš se lahko, da čisto izpustiš nekatere commite. To je omogočeno s `pick` -- izklop `pick` opcije pomeni, da bi rad commit izpustil.", + "* Nenazadnje, commite lahko tudi stisnemo. Nažalost naše stopnje tega ne podpirajo zaradi logističnih razlogov, zato bom preskočil podrobnosti tega. Toda če povzamem -- omogoča združevanje commitov.", + "", + "Super! Poglejmo primer." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Ko pritisneš gumb, se bo pojavilo interaktivno okno. Prerazporedi nekaj commitov okoli (ali pa jih odstrani z omit) in poglej rezultat!" + ], + "afterMarkdowns": [ + "Boom! Git je na dno skopiral commite v točno takšnem vrstnem redu, kot si ga določil v oknu." + ], + "command": "git rebase -i HEAD~4 --aboveAll", + "beforeCommand": "git commit; git commit; git commit; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Za dokončanje te stopnje naredi interaktvini rebase in doseži vrstni red, kot je predstavljen v ciljni vizualizaciji. Vedno lahko razveljavjiš z `undo` ali ponastaviš z `reset` ukazom, da popraviš napake :D" + ] + } + } + ] + }, + "pl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Interaktywny Rebase w Gitcie", + "", + "Cherry-pick'ing jest świetny, gdy wiesz, które commity (_oraz_ znasz ich hasze) chcesz przenieść - trudno jest dyskutować z prostotą, którą zapewnia.", + "", + "Ale co w sytuacji, gdy nie wiesz, które commity chcesz przenieść? Na szczęście git jest przygotowany również na tą sytuację! Możemy wykorzystać do tego interaktywny rebasing - to najlepszy sposób, aby przejrzeć serię commitów, które zamierzasz rebase'ować.", + "", + "Przejdźmy do szczegółów..." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Wszystkie interaktywne znaczniki rebase używają polecenia `rebase` z opcją `-i`.", + "", + "Jeśli włączysz tę opcję, git otworzy okno, aby pokazać ci, które commity mają być skopiowane poniżej wskazanego celu (np. HEAD'a) do rebase'a. W oknie pokażą się również wiadomości i hasze commitów, co zdecydowanie ułatwia zrozumienie co jest czym.", + "", + "Dla \"prawdziwego\" gita, otwarte okno oznacza otwarcie pliku w edytorze tekstu takim jak np. `vim`. Dla naszych potrzeb, zbudowałem małe okno dialogowe, które zachowuje się tak samo." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Kiedy otworzy się interaktywne okno dialogowe rebase, masz możliwość zrobienia dwóch rzeczy w naszej aplikacji edukacyjnej:", + "", + "* Możesz zmienić kolejność commitów poprzez zmianę ich kolejności w oknie (przeciągając je i upuszczając).", + "* Możesz zdecydować się na całkowite pominięcie niektórych commitów. Jest to oznaczone przez `pick` -- wpisanie `pick` off oznacza, że nie chcesz uwzględnić tego commitu.", + "", + "* Warto wspomnieć, że w prawdziwym interaktywnym rebasie możesz zrobić wiele innych rzeczy, takich jak squash (łączenie) commitów, poprawianie wiadomości commitów, a nawet edycja samych commitów. Dla naszych potrzeb jednak skupimy się na tych dwóch operacjach powyżej. *", + "", + "Świetnie! Spójrz na przykład." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Po naciśnięciu przycisku, pojawi się interaktywne okno rebase'owania. Zmień kolejność niektórych commitów (lub usuń niektóre z nich, a co!) i zobacz wynik!" + ], + "afterMarkdowns": [ + "Boom! Git skopiował commity w ten sam sposób w jaki podałeś to w oknie." + ], + "command": "git rebase -i HEAD~4 --aboveAll", + "beforeCommand": "git commit; git commit; git commit; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Aby ukończyć ten poziom, zrób interaktywny rebase i osiągnij kolejność pokazaną w wizualizacji celu. Pamiętaj, że zawsze możesz użyć komend `undo` lub `reset` aby naprawić błędy :D" + ] + } + } + ] + }, } }; diff --git a/src/levels/rampup/relativeRefs.js b/src/levels/rampup/relativeRefs.js index 2fd6e3f1..0cee8da9 100644 --- a/src/levels/rampup/relativeRefs.js +++ b/src/levels/rampup/relativeRefs.js @@ -9,11 +9,16 @@ exports.level = { "zh_CN": "相对引用(^)", "zh_TW": "相對引用(^)", "es_AR": "Referencias relativas (^)", + "es_ES": "Referencias relativas (^)", "pt_BR": "Referências relativas (^)", + "gl" : "Referencias relativas (^)", "de_DE": "Relative Referenzen (^)", "ru_RU": "Относительные ссылки (^)", "ko" : "상대 참조 (^) (Relative Refs)", - "uk": "Відносні посилання" + "uk": "Відносні посилання", + "vi": "Tham chiếu tương đối (^)", + "sl_SI": "Relativne Reference (^)", + "pl": "Referencje względne (^)", }, "hint": { "en_US": "Remember the Caret (^) operator!", @@ -21,12 +26,17 @@ exports.level = { "ja" : "相対リファレンス(^)を思い出して!", "de_DE": "Denk an den Dach-Operator (^)!", "es_AR": "¡No te olvides del operador ^!", + "es_ES": "¡No te olvides del operador ^!", "pt_BR": "Não se esqueça do operador circunflexo (^)", + "gl" : "Non se esqueza do operador circunflexo (^)", "zh_CN": "记住操作符(^)!", "zh_TW": "不要忘記插入(^)符號!", "ru_RU": "Не забудь оператор `^`", "ko" : "(^)연산자를 기억하세요!", - "uk": "Не забудь оператор `^`" + "uk": "Не забудь оператор `^`", + "vi": "Đừng quên dấu mũ (^)!", + "sl_SI": "Spomni se na (^) operator!", + "pl": "Pamiętaj o operatorze karetu (^)!", }, "startDialog": { "en_US": { @@ -66,16 +76,16 @@ exports.level = { "beforeMarkdowns": [ "Let's look at the Caret (^) operator first. Each time you append that to a ref name, you are telling Git to find the parent of the specified commit.", "", - "So saying `master^` is equivalent to \"the first parent of `master`\".", + "So saying `main^` is equivalent to \"the first parent of `main`\".", "", - "`master^^` is the grandparent (second-generation ancestor) of `master`", + "`main^^` is the grandparent (second-generation ancestor) of `main`", "", - "Let's check out the commit above master here" + "Let's check out the commit above main here." ], "afterMarkdowns": [ - "Boom! Done. Way easier than typing the commit hash" + "Boom! Done. Way easier than typing the commit hash." ], - "command": "git checkout master^", + "command": "git checkout main^", "beforeCommand": "git commit" } }, @@ -83,7 +93,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "You can also reference `HEAD` as a relative ref. Let's use that a couple of times to move upwards in the commit tree" + "You can also reference `HEAD` as a relative ref. Let's use that a couple of times to move upwards in the commit tree." ], "afterMarkdowns": [ "Easy! We can travel backwards in time with `HEAD^`" @@ -141,16 +151,16 @@ exports.level = { "beforeMarkdowns": [ "Regardons l'opérateur circonflexe (^) d'abord. Chaque fois que vous le faites suivre un nom de référence, vous êtes en train de demander à Git de trouver le parent du commit spécifié.", "", - "Ainsi, `master^` est équivalent à \"le premier parent de `master`\".", + "Ainsi, `main^` est équivalent à \"le premier parent de `main`\".", "", - "`master^^` est le grand-parent (ancêtre de seconde génération) de `master`", + "`main^^` est le grand-parent (ancêtre de seconde génération) de `main`", "", - "Faisons un checkout du commit avant master." + "Faisons un checkout du commit avant main." ], "afterMarkdowns": [ "Boum ! Fini. Bien plus facile qu'écrire l'identifiant du commit." ], - "command": "git checkout master^", + "command": "git checkout main^", "beforeCommand": "git commit" } }, @@ -216,16 +226,16 @@ exports.level = { "beforeMarkdowns": [ "Schauen wir uns zuerst den Dach-Operator (`^`) an. Jedes mal wenn du ihn hinter einen Referenz-Namen setzt, sagst du Git damit, dass es zum Vorgänger des angegebenen Commits gehen soll.", "", - "Das heißt `master^` ist gleichbedeutend mit \"direkter Vorgänger des Commits, auf den `master` zeigt\".", + "Das heißt `main^` ist gleichbedeutend mit \"direkter Vorgänger des Commits, auf den `main` zeigt\".", "", - "`master^^` ist also der Vorgänger des Vorgängers von `master`.", + "`main^^` ist also der Vorgänger des Vorgängers von `main`.", "", - "Wir checken jetzt mal den Commit vor `master` aus:" + "Wir checken jetzt mal den Commit vor `main` aus:" ], "afterMarkdowns": [ "Bämm! Fertig. Einfacher, als den Commit-Hash zu tippen (oder zu kopieren)." ], - "command": "git checkout master^", + "command": "git checkout main^", "beforeCommand": "git commit" } }, @@ -291,16 +301,16 @@ exports.level = { "beforeMarkdowns": [ "Veamos el operador ^ primero. Cada vez que le agregás eso al nombre de una referencia, le estás diciendo a git que use el padre del commit especificado.", "", - "Entonces, decir `master^` es equivalente a \"el primer padre de `master`\".", + "Entonces, decir `main^` es equivalente a \"el primer padre de `main`\".", "", - "`master^^` es el _abuelo_ (segunda generación de ancestros) de `master`", + "`main^^` es el _abuelo_ (segunda generación de ancestros) de `main`", "", - "Veamos el commit que está antes de master acá" + "Veamos el commit que está antes de main acá." ], "afterMarkdowns": [ - "¡Boom! Ahí está. Mucho más simple que tipear el hash de ese commit" + "¡Boom! Ahí está. Mucho más simple que tipear el hash de ese commit." ], - "command": "git checkout master^", + "command": "git checkout main^", "beforeCommand": "git commit" } }, @@ -308,7 +318,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "También podés referenciar a `HEAD` como una referencia relativa. Usémoslo un par de veces para movernos hacia atrás en nuestro árbol" + "También podés referenciar a `HEAD` como una referencia relativa. Usémoslo un par de veces para movernos hacia atrás en nuestro árbol." ], "afterMarkdowns": [ "¡Fácil! Podemos volver en el tiempo con `HEAD^`" @@ -329,6 +339,81 @@ exports.level = { } ] }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Referencias relativas", + "", + "Moverse por git usando los hashes de los commits puede volverse un tanto tedioso. En el mundo real no vas a tener una visualización de commits tan linda en la terminal, así que vas a tener que usar `git log` para ver los hashes.", + "", + "Peor aún, los hashes en general son mucho más largos en el git real, también. Por ejemplo, el hash del commit que introduje en el nivel anterior es `fed2da64c0efc5293610bdd892f82a58e8cbc5d8`. No es algo particularmente fácil de nombrar...", + "", + "Lo interesante es que git es bastante astuto con los hashes. Sólo requiere que especifiques una cantidad de caracteres suficientes para identificar unívocamente al commit. Entonces, yo podría simplemente tipear `fed2` en lugar de esa cadena larga de arriba." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Como ya dije, especificar los commits por su hash no es la manera más conveniente, y por eso git tiene referencias relativas. ¡Son geniales!", + "", + "Con las referencias relativas puedes arrancar de algún lugar recordable (como la rama `bugFix`, o `HEAD`) y trabajar desde ahí.", + "", + "Los commits relativos son poderosos, pero ahora vamos a presentar sólo dos formas simples:", + "", + "* Moverse un commit hacia atrás con `^`", + "* Moverse una cantidad de commits hacia atrás con `~`" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Veamos el operador ^ primero. Cada vez que le agregas eso al nombre de una referencia, le estás diciendo a git que use el padre del commit especificado.", + "", + "Entonces, decir `main^` es equivalente a \"el primer padre de `main`\".", + "", + "`main^^` es el _abuelo_ (segunda generación de ancestros) de `main`", + "", + "Veamos el commit que está antes de main aquí." + ], + "afterMarkdowns": [ + "¡Zas! Ahí está. Mucho más simple que escribir el hash de ese commit." + ], + "command": "git checkout main^", + "beforeCommand": "git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "También puedes referenciar a `HEAD` como una referencia relativa. Usémoslo un par de veces para movernos hacia atrás en nuestro árbol." + ], + "afterMarkdowns": [ + "¡Fácil! Podemos volver en el tiempo con `HEAD^`" + ], + "command": "git checkout C3; git checkout HEAD^; git checkout HEAD^; git checkout HEAD^", + "beforeCommand": "git commit; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para completar este nivel, haz checkout sobre el padre del commit de `bugFix`. Esto va a detachear a `HEAD`.", + "", + "Puedes especificar el hash si quieres, pero mejor ¡trata de usar la referencia relativa!" + ] + } + } + ] + }, "pt_BR": { "childViews": [ { @@ -366,16 +451,16 @@ exports.level = { "beforeMarkdowns": [ "Vamos dar uma olhada no operador circunflexo (^) primeiro. Cada vez que você adicioná-lo a um nome de referência, você está dizendo ao Git para encontrar o pai do commit especificado.", "", - "Então, dizer `master^` é equivalente a \"o primeiro pai do `master`\".", + "Então, dizer `main^` é equivalente a \"o primeiro pai do `main`\".", "", - "`master^^` é o avô (ancestral de segunda geração) do `master`", + "`main^^` é o avô (ancestral de segunda geração) do `main`", "", - "Vamos fazer checkout do commit logo acima do master" + "Vamos fazer checkout do commit logo acima do main." ], "afterMarkdowns": [ - "Boom! Pronto. Muito mais fácil que digitar o hash do commit" + "Boom! Pronto. Muito mais fácil que digitar o hash do commit." ], - "command": "git checkout master^", + "command": "git checkout main^", "beforeCommand": "git commit" } }, @@ -383,7 +468,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Você também pode usar o `HEAD` como parte de uma referência relativa. Vamos usar isso para nos mover para cima algumas vezes na árvore de commits" + "Você também pode usar o `HEAD` como parte de uma referência relativa. Vamos usar isso para nos mover para cima algumas vezes na árvore de commits." ], "afterMarkdowns": [ "Fácil! Podemos viajar para trás no tempo com `HEAD^`" @@ -404,6 +489,81 @@ exports.level = { } ] }, + "gl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Referencias relativas", + "", + "Moverse por a árbore de git usando os códigos hash dos commits pode volverse un pouco tedioso. Neste mundo real non vas ter unha visualización dos commits tan bonita no terminal, así que vas ter que usar `git log` para ver cada código hash.", + "", + "Inda peor, os códigos hash són xeralmente moito máis grandes no mundo real. Por exemplo, o hash do commit que introduxemos no nivel anterior é `fed2da64c0efc5293610bdd892f82a58e8cbc5d8`. Non é algo sinxelo de lembrar.", + "", + "O bo é que git aínda afina cos hashes. El só precisa que expecifiques a cantidade mínima de caracteres suficientes para identificar unívocamente ó commit. Entón eu podo escribir `fed2` e non o hash completo." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Como xa dixemos, indicar os commits polo seu código hash non é a forma máis convinte, e é por eso que git ten referencias relativas. ¡Son a caña!", + "", + "Cas referencias relativas, podes comezar por un punto sinxelo de lembrar (como a rama `bugFix` ou o `HEAD`) e referenciar a partir de ahí.", + "", + "Os commits relativos son poderosos, pero agora imos presentar só dous formas sinxelas:", + "", + "* Moverse un commit por riba con `^`", + "* Mover unha cantidade de commits atrás con `~`" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Votémoslle unha ollada o operador (^) primeiro. Cada vez que o engadimos a unha referencia, estaslle dicindo a commit que queres o pai de esa referencia.", + "", + "Entón, dicir `main^` é equivalente a \"o primeiro pai do `main`\".", + "", + "`main^^` é o avó (ancestral de segunda xeración) do `main`", + "", + "Imos facer checkout do commit que está enriba de main." + ], + "afterMarkdowns": [ + "Boom! Ahí o tes. Moito máis rápido que por o hash do commit." + ], + "command": "git checkout main^", + "beforeCommand": "git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Tamén podes usar o `HEAD` como parte dunha referencia relativa. Ímolo utilizar para nos mover uns commits cara arriba na árbore." + ], + "afterMarkdowns": [ + "¡Chupado! Podemos viaxar cara atrás no tempo con `HEAD^`" + ], + "command": "git checkout C3; git checkout HEAD^; git checkout HEAD^; git checkout HEAD^", + "beforeCommand": "git commit; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para completar este nivel, fai checkout do commit pai de `bugFix`. Iso soltará o `HEAD`.", + "", + "¡Podes indicar o hash que queiras, pero intenta empregar as referencias relativas, é moito mellor!" + ] + } + } + ] + }, "zh_CN": { "childViews": [ { @@ -441,16 +601,16 @@ exports.level = { "beforeMarkdowns": [ "首先看看操作符 (^)。把这个符号加在引用名称的后面,表示让 Git 寻找指定提交记录的父提交。", "", - "所以 `master^` 相当于“`master` 的父节点”。", + "所以 `main^` 相当于“`main` 的父节点”。", "", - "`master^^` 是 `master` 的第二个父节点", + "`main^^` 是 `main` 的第二个父节点", "", - "现在咱们切换到 master 的父节点" + "现在咱们切换到 main 的父节点" ], "afterMarkdowns": [ "搞定。这种方式是不是比输入哈希值方便多了?!" ], - "command": "git checkout master^", + "command": "git checkout main^", "beforeCommand": "git commit" } }, @@ -516,16 +676,16 @@ exports.level = { "beforeMarkdowns": [ "首先看看插入(^)這一個符號。把這個符號接在某一個 reference 後面,就表示你告訴 git 去找到該 reference 所指向的 commit 的 parent commit。", "", - "所以 `master^` 相當於 \"`master` 的 parent commit\"。", + "所以 `main^` 相當於 \"`main` 的 parent commit\"。", "", - " `master^^` 是 `master` 的 grandparent commit(往前推兩代)", + " `main^^` 是 `main` 的 grandparent commit(往前推兩代)", "", "切換到 master的 parent commit" ], "afterMarkdowns": [ "看吧!完成了。這種方式比輸入代表 commit 的 hash 值簡單多了!" ], - "command": "git checkout master^", + "command": "git checkout main^", "beforeCommand": "git commit" } }, @@ -591,16 +751,16 @@ exports.level = { "beforeMarkdowns": [ "まずはカレット(^)から始めましょう。リファレンス名にカレットを追加すると、指定コミットの親コミットを見つけるようにとgitに命令を出しています。", "", - "なので `master^`と記述すれば、\"`master`の一個上の親\"、という意味になります。", + "なので `main^`と記述すれば、\"`main`の一個上の親\"、という意味になります。", "", - "そして`master^^`とはその親の一つの上のコミット(2代前の親)を指します。", + "そして`main^^`とはその親の一つの上のコミット(2代前の親)を指します。", "", "masterの上のコミットをここで見てみましょう" ], "afterMarkdowns": [ "やりました!コミットハッシュを書くよりずっと簡単ですね。" ], - "command": "git checkout master^", + "command": "git checkout main^", "beforeCommand": "git commit" } }, @@ -666,16 +826,16 @@ exports.level = { "beforeMarkdowns": [ "Для начала рассмотрим оператор каретки (^). Когда мы добавляем его к имени ссылки, Git воспринимает это как указание найти родителя указанного коммита.", "", - "Так что `master^` означает \"первый предок ветки `master`\".", + "Так что `main^` означает \"первый родитель ветки `main`\".", "", - "`master^^` означает предок предка ветки `master`", + "`main^^` означает прародитель (родитель родителя) `main`", "", - "Получим предка ветки `master` на практике" + "Давайте переключимся на коммит Выше `main`" ], "afterMarkdowns": [ "Опачки! Готово. Сильно проще, чем поиск и указание хеша." ], - "command": "git checkout master^", + "command": "git checkout main^", "beforeCommand": "git commit" } }, @@ -704,7 +864,7 @@ exports.level = { } ] }, - "ko": { + "ko": { "childViews": [ { "type": "ModalAlert", @@ -741,16 +901,16 @@ exports.level = { "beforeMarkdowns": [ "먼저 캐럿 (^) 연산자 부터 알아보겠습니다. 참조 이름에 하나씩 추가할 때마다, 명시한 커밋의 부모를 찾게 됩니다.", "", - "`master^`는 \"`master`의 부모\"와 같은 의미 입니다.", + "`main^`는 \"`main`의 부모\"와 같은 의미 입니다.", "", - "`master^^` 는 \"`master`의 조부모(부모의 부모)\"를 의미합니다", + "`main^^` 는 \"`main`의 조부모(부모의 부모)\"를 의미합니다", "", - "master 위에 있는 부모를 체크아웃 해 봅시다." + "main 위에 있는 부모를 체크아웃 해 봅시다." ], "afterMarkdowns": [ "Boom! 됬습니다. 커밋의 해시를 입력하는 것보다 훨씬 쉬운 방법입니다." ], - "command": "git checkout master^", + "command": "git checkout main^", "beforeCommand": "git commit" } }, @@ -816,16 +976,16 @@ exports.level = { "beforeMarkdowns": [ "Розберемось спочатку з оператором каретки (^). Кожна каретка додана до посилання (напр. до імені коміту) вказує git що потрібно знайти батька посилання до якого застосована каретка.", "", - "Тож `master^` тотожнє до \"перший предок посилання `master`\".", + "Тож `main^` тотожнє до \"перший предок посилання `main`\".", "", - "`master^^` це дідусь (предок другого покоління) посилання `master`", + "`main^^` це дідусь (предок другого покоління) посилання `main`", "", - "Давайте перейдемо на коміт трохи вище від master:" + "Давайте перейдемо на коміт трохи вище від main:" ], "afterMarkdowns": [ "Бум! Готово. Трохи простіше ніж набирати хеш коміту" ], - "command": "git checkout master^", + "command": "git checkout main^", "beforeCommand": "git commit" } }, @@ -853,6 +1013,231 @@ exports.level = { } } ] - } + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Tham chiếu tương đối", + "", + "Dịch chuyển trong Git bằng cách chỉ định mã băm(hash) của commit cỏ vẻ hơi buồn tẻ. Trong đời thực thì sẽ không có mô tả git trực quan ngay bên cạnh terminal của bạn đâu, nên nếu bạn muốn nhìn mã băm của commit thì phải dùng `git log` thôi.", + "", + "Hơn nữa, mã băm thực tế thường dài hơn rất nhiều. Ví dụ, mã băm của commit được giới thiệu trong phần trước là `fed2da64c0efc5293610bdd892f82a58e8cbc5d8`. Đọc mà xoắn hết cả lưỡi...", + "", + "Được cái là Git cũng khá thông minh về mã băm. Nó chỉ yêu cầu bạn chỉ định mã băm đủ để xác định commit. Cho nên tôi có thể đơn giản chỉ cần gõ `fed2` thay vì cái chuỗi dài ngoằng phía trên." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Như tôi đã nói, xác định commit bằng mã băm của nó chẳng hề thuận tiện tẹo nào, đó là tại sao Git có những `tham chiếu tương đối`. Chúng rất tuyệt vời!", + "", + "Với tham chiếu tương đối, bạn có thể bắt đầu từ những nơi có thể ghi nhớ được (như là nhánh `bugFix` hoặc `HEAD`) và làm việc trên đó.", + "", + "Những commits tương đối rất mạnh mẽ, nhưng chúng tôi sẽ chỉ giới thiệu 2 loại đơn giản sau:", + "", + "* Dịch chuyển 1 commit lên trên trong 1 lần với `^`", + "* Dịch chuyển nhiều commit lên trên trong 1 lần với `~`" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Xem thử cái dấu mũ (^) trước nào. Mỗi lần bạn nối nó với một cái tên tham chiếu, bạn đang ra lệnh cho Git tìm kiếm cha của một commit cụ thể.", + "", + "Cho nên `main^` nghĩa là \"cha đầu tiên của `main`\".", + "", + "`main^^` là ông nội (tổ tiên thế hệ 2) của `main`", + "", + "Thử nhảy sang commit trước main nào" + ], + "afterMarkdowns": [ + "BÙUM! Đã xong. Đơn giản hơn gõ mã băm nhiều" + ], + "command": "git checkout main^", + "beforeCommand": "git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Bạn cũng có thể dùng `HEAD` như là tham chiếu tương đối. Thử dùng nó để leo commit vài lần nào" + ], + "afterMarkdowns": [ + "Game là dễ! Du hành ngược thời gian với `HEAD^`" + ], + "command": "git checkout C3; git checkout HEAD^; git checkout HEAD^; git checkout HEAD^", + "beforeCommand": "git commit; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Để hoàn thành cấp độ này, nhảy sang cha của `bugFix`. Tức là tháo `HEAD`.", + "", + "Nếu muốn thì bạn có thể dùng mã băm, nhưng thế thì còn gì vui nữa dùng tham chiếu tương đối đi!" + ] + } + } + ] + }, + "sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Relativne Reference", + "", + "Premikanje po Gitu z določanjem hashev commitov je lahko včasih nerodno. V praksi ne boš imel na voljo lepe vizualizacije drevesa zraven ukaznega terminala, zato boš moral uporabljati `git log`, da boš videl hashe.", + "", + "Hashi so ponavadi v praksi tudi veliko daljši. Naprimer, hash commita, predstavljenega v prejšnji stopnji, je `fed2da64c0efc5293610bdd892f82a58e8cbc5d8`. Ni ravno preprosto za izgovoriti ...", + "", + "Pozitivna stran je, da je Git pameten glede hashev. Zahteva, da napišeš le toliko znakov hasha, da lahko prepozna unikaten commit. Tako lahko napišem `fed2`, namesto dolge verzije zgoraj." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Kot sem rekel, izbiranje commitov po njihovih hashih ni ravno najpriročnejša stvar na svetu, zato ima Git relativne reference. In te so super!", + "", + "Z relativni referencami lahko izhajaš iz nekje (npr. branch `bugFix` ali `HEAD`) in delaš od tam.", + "", + "Relativni commiti so močni in obsegajoči, ampak tu bomo predstavili dva preprosta:", + "", + "* Premikanje navzgor en commit naenkrat z `^`", + "* Premikanje navzgor n-krat z `~`" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Poglejmo najprej operator `^`. Vsakič, ko pripneš to imenu reference, poveš Gitu, naj najde starša tega commita.", + "", + "Torej `main^` je isto kot \"prvi starš brancha `main`\".", + "", + "`main^^` je stari starš (prednik druge generacije) `main`.", + "", + "Checkoutajmo sedaj commit nad masterjem." + ], + "afterMarkdowns": [ + "Boom! Narejeno. Veliko enostavneje kot tipkanje hasha commita." + ], + "command": "git checkout main^", + "beforeCommand": "git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Prav tako se lahko sklicuješ na `HEAD` kot relativno referenco. Uporabimo to nekajkrat, da se pomakenmo višje po drevesu commitov." + ], + "afterMarkdowns": [ + "Enostavno! Lahko potujemo nazaj v čas z `HEAD^`." + ], + "command": "git checkout C3; git checkout HEAD^; git checkout HEAD^; git checkout HEAD^", + "beforeCommand": "git commit; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Za dokončanje te stopnje, checkoutaj starša commita `bugFix`. To bo ločilo `HEAD`.", + "", + "Hash lahko določiš, če želiš, ampak probaj raje z relativnimi referencami!" + ] + } + } + ] + }, + "pl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Relatywne referencje", + "", + "Poruszanie się w Gitcie poprzez określanie haszy commitów może być trochę nudne. W prawdziwym świecie nie będziesz miał ładnej wizualizacji drzewa commitów obok swojego terminalu (chyba, że będziesz używać Fork'a lub TortoiseGit'a). Będziesz musiał użyć `git log` aby zobaczyć hasz.", + "", + "Co więcej, hasz jest zazwyczaj o wiele dłuższy w prawdziwym Gitcie. Na przykład, hash commitu, które był na początku poprzedniego poziomu to `fed2da64c0efc5293610bdd892f82a58e8cbc5d8`. Spróbuj to przeczytać!", + "", + "Plusem jest to, że Git jest sprytny jeżeli chodzi o hasze. Wymaga jedynie podania tylu znaków haszu, aż do momentu, gdy jednoznacznie zidentyfikuje konkretny commit. Dlatego mogę wpisać jedynie `fed2` zamiast długiego łańcucha powyżej." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Jak już powiedzieliśmy, wybieranie commitów używając ich hasza nie jest najprzyjemniejszą rzeczą w życiu, dlatego Git ma referencje względne. Są niesamowite!", + "", + "Korzystając z referencji względnych, możesz zacząć od miejsca, które zapamiętasz (jak np. gałąź `bugFix` lub `HEAD`) i pracować stamtąd.", + "", + "Relatywne commity są potężne, ale pokażemy tu tylko dwie proste sytuacje:", + "", + "* Poruszanie się wstecz o jeden commit `^`", + "* Poruszanie się wstecz o ileś commitów `~`" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Spójrzmy najpierw na operator Karety / daszek (^). Za każdym razem, gdy dodajesz go do referencji względnej, mówisz Gitowi, aby znalazł rodzica określonego commita.", + "", + "Więc wpisując `main^` mamy na myśli \"pierwszego rodzica z gałęzi `main`\".", + "", + "`main^^` to dziadek (przodek drugiego stopnia) gałęzi `main`", + "", + "Zcheckoutujmy commit powyżej `main`." + ], + "afterMarkdowns": [ + "Boom! Zrobione. O wiele łatwiej niż wpisując hasz commitu." + ], + "command": "git checkout main^", + "beforeCommand": "git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Możesz również odwołać się do `HEAD` jako referencji względnej. Użyjmy tego kilka razy, aby przesunąć się w górę drzewa commitów." + ], + "afterMarkdowns": [ + "Łatwizna! Możemy podróżować do tyłu w czasie używając `HEAD^`" + ], + "command": "git checkout C3; git checkout HEAD^; git checkout HEAD^; git checkout HEAD^", + "beforeCommand": "git commit; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Aby ukończyć ten poziom, zcheckoutuj commit'a-rodzica z gałęzi `bugFix`. To spowoduje odczepienie `HEAD`a.", + "", + "Możesz wybrać commit'a po haszu jeżeli chcesz, ale spróbuj wykorzystać to czego się nauczyłeś i użyć referencji względnej!" + ] + } + } + ] + }, } }; diff --git a/src/levels/rampup/relativeRefs2.js b/src/levels/rampup/relativeRefs2.js index c3ac4171..8081ed98 100644 --- a/src/levels/rampup/relativeRefs2.js +++ b/src/levels/rampup/relativeRefs2.js @@ -1,6 +1,6 @@ exports.level = { "goalTreeString": "{\"branches\":{\"master\":{\"target\":\"C6\",\"id\":\"master\"},\"bugFix\":{\"target\":\"C0\",\"id\":\"bugFix\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C2\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C3\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C5\"],\"id\":\"C6\"}},\"HEAD\":{\"target\":\"C1\",\"id\":\"HEAD\"}}", - "solutionCommand": "git branch -f master C6;git checkout HEAD~1;git branch -f bugFix HEAD~1", + "solutionCommand": "git branch -f main C6;git checkout HEAD~1;git branch -f bugFix HEAD~1", "startTree": "{\"branches\":{\"master\":{\"target\":\"C4\",\"id\":\"master\"},\"bugFix\":{\"target\":\"C5\",\"id\":\"bugFix\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C2\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C3\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C5\"],\"id\":\"C6\"}},\"HEAD\":{\"target\":\"C2\",\"id\":\"HEAD\"}}", "hint": { "en_US": "You'll need to use at least one direct reference (hash) to complete this level", @@ -8,25 +8,35 @@ exports.level = { "zh_CN": "这一关至少要用到一次直接引用 (即哈希值)", "zh_TW": "這一關至少要用到一次直接參考(hash)", "es_AR": "Vas a necesitar usar al menos una referencia directa (hash) para completar este nivel", + "es_ES": "Vas a necesitar usar al menos una referencia directa (hash) para completar este nivel", "pt_BR": "Você precisará usar pelo menos uma referência direta (hash) para completar este nível", + "gl" : "Precisarás usar polo menos unha referencia directa (hash) para completar este nivel", "de_DE": "Du musst mindestens einen Hash benutzen, um dieses Level zu schaffen", "ja" : "このレベルをクリアするには少なくとも一つの直接リファレンス(hash)を使用する必要があります", "ru_RU": "Понадобится использовать как минимум одну прямую ссылку (хеш), чтобы пройти этот уровень", "ko" : "이번 레벨을 완료하려면 최소 한번은 직접 참조(해시)를 사용해야 합니다.", - "uk": "Тобі потрібно використати як мінімум одне пряме посилання (хеш) щоб пройти цей рівень" + "uk": "Тобі потрібно використати як мінімум одне пряме посилання (хеш) щоб пройти цей рівень", + "vi": "Bạn sẽ cần dùng ít nhất một tham chiếu trực tiếp (mã băm) để hoàn thành cấp độ này", + "sl_SI": "Moral boš uporabiti vsaj eno direktno referenco (hash) za dokončanje te stopnje.", + "pl": "Aby ukończyć ten poziom, musisz użyć co najmniej jednego bezpośredniej referencji (hasza).", }, "name": { "en_US": "Relative Refs #2 (~)", "de_DE": "Relative Referenzen #2 (~)", "ja" : "相対リファレンス その2 (~)", "es_AR": "Referencias relativas #2 (~)", + "es_ES": "Referencias relativas #2 (~)", "pt_BR": "Referências relativas #2 (~)", + "gl" : "Referencias relativas #2 (~)", "fr_FR": "Références relatives #2 (~)", "zh_CN": "相对引用2(~)", "zh_TW": "相對引用二(~)", "ru_RU": 'Относительные ссылки №2', "ko" : "상대 참조 #2 (~)", - "uk": "Відносні посилання №2" + "uk": "Відносні посилання №2", + "vi": "Tham chiếu tương đối #2 (~)", + "sl_SI": "Relativne Reference #2 (~)", + "pl": "Referencje względne #2 (~)" }, "startDialog": { "en_US": { @@ -40,7 +50,7 @@ exports.level = { "Say you want to move a lot of levels up in the commit tree. It might be tedious to type `^` several times, so Git also has the tilde (~) operator.", "", "", - "The tilde operator (optionally) takes in a trailing number that specifies the number of parents you would like to ascend. Let's see it in action" + "The tilde operator (optionally) takes in a trailing number that specifies the number of parents you would like to ascend. Let's see it in action." ] } }, @@ -67,9 +77,9 @@ exports.level = { "", "One of the most common ways I use relative refs is to move branches around. You can directly reassign a branch to a commit with the `-f` option. So something like:", "", - "`git branch -f master HEAD~3`", + "`git branch -f main HEAD~3`", "", - "moves (by force) the master branch to three parents behind HEAD." + "moves (by force) the main branch to three parents behind HEAD." ] } }, @@ -82,7 +92,7 @@ exports.level = { "afterMarkdowns": [ "There we go! Relative refs gave us a concise way to refer to `C1` and branch forcing (`-f`) gave us a way to quickly move a branch to that location." ], - "command": "git branch -f master HEAD~3", + "command": "git branch -f main HEAD~3", "beforeCommand": "git commit; git commit; git commit; git checkout -b bugFix" } }, @@ -92,7 +102,7 @@ exports.level = { "markdowns": [ "Now that you have seen relative refs and branch forcing in combination, let's use them to solve the next level.", "", - "To complete this level, move `HEAD`, `master`, and `bugFix` to their goal destinations shown." + "To complete this level, move `HEAD`, `main`, and `bugFix` to their goal destinations shown." ] } } @@ -136,9 +146,9 @@ exports.level = { "", "Una de las formas más comunes en que uso las referencias relativas es para mover las ramas. Podés reasignar directamente una rama a un commit usando la opción `-f`. Así que algo como:", "", - "`git branch -f master HEAD~3`", + "`git branch -f main HEAD~3`", "", - "Mueve (forzadamente) la rama master tres padres atrás de HEAD." + "Mueve (forzadamente) la rama main tres padres atrás de HEAD." ] } }, @@ -151,7 +161,7 @@ exports.level = { "afterMarkdowns": [ "¡Ahí vamos! Las referencias relativas nos dieron una manera concisa de referenciar a `C1`, y forzar la rama (`-f`) nos dio una manera rápida de mover la rama a esa ubicación" ], - "command": "git branch -f master HEAD~3", + "command": "git branch -f main HEAD~3", "beforeCommand": "git commit; git commit; git commit; git checkout -b bugFix" } }, @@ -161,7 +171,76 @@ exports.level = { "markdowns": [ "Ahora que viste las referencias relativas y el forzar ramas combinados, usémoslos para resolver el siguiente nivel.", "", - "Para completar este nivel, mové `HEAD`, `master` y `bugFix` a sus destinos finales." + "Para completar este nivel, mové `HEAD`, `main` y `bugFix` a sus destinos finales." + ] + } + } + ] + }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### El operador \"~\"", + "", + "Digamos que quieres moverte un montón de niveles atrás en tu árbol de commits. Podría ser tedioso escribir `^` muchas veces, por lo que git tiene el operador ~.", + "", + "", + "El operador ~ (opcionalmente) toma una cantidad que especifica la cantidad de padres que quieres volver hacia atrás. Veámoslo en acción" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Especifiquemos una cantidad de commits hacia atrás con `~`." + ], + "afterMarkdowns": [ + "¡Zas! Bien conciso -- las referencias relativas la rompen." + ], + "command": "git checkout HEAD~4", + "beforeCommand": "git commit; git commit; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Forzando las ramas", + "", + "Ahora que eres un experto en las referencias relativas, *usémoslas* para algo.", + "", + "Una de las formas más comunes en que uso las referencias relativas es para mover las ramas. Puedes reasignar directamente una rama a un commit usando la opción `-f`. Algo así como:", + "", + "`git branch -f main HEAD~3`", + "", + "Mueve (forzadamente) la rama main tres padres por detrás de HEAD." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Veamos ese comando previo en acción" + ], + "afterMarkdowns": [ + "¡Allá vamos! Las referencias relativas nos proporcionaron una manera concisa de referenciar a `C1`, y forzar la rama (`-f`) nos dio una manera rápida de mover la rama a esa ubicación" + ], + "command": "git branch -f main HEAD~3", + "beforeCommand": "git commit; git commit; git commit; git checkout -b bugFix" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Ahora que viste las referencias relativas y el forzar ramas combinados, usémoslos para resolver el siguiente nivel.", + "", + "Para completar este nivel, mueve `HEAD`, `main` y `bugFix` a sus destinos finales." ] } } @@ -205,9 +284,9 @@ exports.level = { "", "Uma das situações mais comuns na qual eu uso referências relativas é quando quero trocar ramos de lugar. Você pode redefinir diretamente o commit para o qual um ramo aponta com a opção `-f`. Desta forma, o seguinte comando:", "", - "`git branch -f master HEAD~3`", + "`git branch -f main HEAD~3`", "", - "Move (à força) o ramo master 3 ancestrais acima do HEAD." + "Move (à força) o ramo main 3 ancestrais acima do HEAD." ] } }, @@ -218,9 +297,9 @@ exports.level = { "Vejamos o comando anterior em ação" ], "afterMarkdowns": [ - "Aqui vamos nós! As referências relativas nos deram uma forma concisa de nos referirmos ao `C1`, e a movimentação de ramos (com `-f`) nos deu uma forma de apontar rapidamente um ramo para esse local" + "Aqui vamos nós! As referências relativas nos deram uma forma concisa de nos referirmos ao `C1`, e a movimentação de ramos (com `-f`) nos deu uma forma de apontar rapidamente um ramo para esse local." ], - "command": "git branch -f master HEAD~3", + "command": "git branch -f main HEAD~3", "beforeCommand": "git commit; git commit; git commit; git checkout -b bugFix" } }, @@ -230,7 +309,76 @@ exports.level = { "markdowns": [ "Agora que você viu referências relativas e movimentação de ramos combinadas, vamos usá-las para resolver o próximo nível.", "", - "Para completar este nível, mova o `HEAD` e os ramos `master` e `bugFix` para os destinos mostrados no objetivo." + "Para completar este nível, mova o `HEAD` e os ramos `main` e `bugFix` para os destinos mostrados no objetivo." + ] + } + } + ] + }, + "gl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### O operador \"~\"", + "", + "Digamos que queres moverte un montón de commits cara atrás nunha árbore de git. Sería moi tedioso escribir `^` moitas veces, e por iso que git tamén ten o operador (`~`).", + "", + "", + "Pódeselle pasar un número (opcionalmente) despois da tilde, especificando o número de commits que se quere mover cara atrás. Mira como é en acción." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Imos especificar un número de commits cara atrás con `~`." + ], + "afterMarkdowns": [ + "¡Veeeña! Ben apuntado -- as referencias relativas son a leche." + ], + "command": "git checkout HEAD~4", + "beforeCommand": "git commit; git commit; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Forzando as ramas", + "", + "Agora que eres un especialista en referencias relativas, imos *usalas* para algunha cousiña.", + "", + "Un dos usos máis comúns para o uso das referencias relativas é para movelas ramas de lugar. Ti podes reasignar directamente unha rama a un commit usando a opción `-f`. Así que con algo coma:", + "", + "`git branch -f main HEAD~3`", + "", + "Move (de forma forzosa) a rama main 3 commits enriba do HEAD." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Vexamos o comando anterior en acción" + ], + "afterMarkdowns": [ + "¡Agora é o a nosa quenda! As referencias relativas nos darán unha forma concisa de nos referír a `C1`, e forzar a rama (con `-f`) deunos unha forma rápida de movela rama `main` a esa posición." + ], + "command": "git branch -f main HEAD~3", + "beforeCommand": "git commit; git commit; git commit; git checkout -b bugFix" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Xa viches as referencias relativas e o movemento de ramas combinadas, ímolas usar para resolver o próximo exercicio.", + "", + "Para completar este nivel, mova o `HEAD` e as ramas `main` e `bugFix` para os destinos mostrados no obxectivo." ] } } @@ -247,7 +395,7 @@ exports.level = { "Disons que vous souhaitez remonter beaucoup de niveaux dans l'arbre des commits. Cela peut être ennuyeux d'utiliser `^` plusieurs fois, ainsi Git a aussi l'opérateur tilde (~).", "", "", - "L'opérateur tilde prend optionnellement à sa suite un nombre qui spécifie le nombre de parents que vous souhaitez remonter. Voyons cela en action" + "L'opérateur tilde prend optionnellement à sa suite un nombre qui spécifie le nombre de parents que vous souhaitez remonter. Voyons cela en action." ] } }, @@ -274,9 +422,9 @@ exports.level = { "", "L'une des principales façons dont j'utilise les références relatives est pour réorganiser les branches. Vous pouvez directement réassigner les branches à un commit avec l'option `-f`. Ainsi quelque chose comme :", "", - "`git branch -f master HEAD~3`", + "`git branch -f main HEAD~3`", "", - "bouge (de force) la branche master à trois parents derrière HEAD." + "bouge (de force) la branche main à trois parents derrière HEAD." ] } }, @@ -284,12 +432,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Voyons l'effet de la précédente commande" + "Voyons l'effet de la précédente commande." ], "afterMarkdowns": [ - "On y est ! Les références relatives nous donne une méthode concise pour référencer `C1` et le forçage de branche (`-f`) nous donne une méthode rapide pour bouger une branche à cet emplacement." + "On y est ! Les références relatives nous donnent une méthode concise pour référencer `C1` et le forçage de branche (`-f`) nous donne une méthode rapide pour bouger une branche à cet emplacement." ], - "command": "git branch -f master HEAD~3", + "command": "git branch -f main HEAD~3", "beforeCommand": "git commit; git commit; git commit; git checkout -b bugFix" } }, @@ -299,7 +447,7 @@ exports.level = { "markdowns": [ "Maintenant que vous avez vu les références relatives et le forçage de branche, utilisons-les pour résoudre le niveau suivant.", "", - "Pour compléter ce niveau, bouger `HEAD`, `master`, et `bugFix` à leurs destinations désignées." + "Pour compléter ce niveau, bouger `HEAD`, `main`, et `bugFix` à leurs destinations désignées." ] } } @@ -313,7 +461,7 @@ exports.level = { "markdowns": [ "### Der \"~\"-Operator", "", - "Nehmen wir an du willst viele Schritte im Commit-Baum zurückgehen. Dann wird es schnell mühsam immer wieder `^` einzugeben; deswegen gibt es in Git den Tilde-Operator `~`.", + "Nehmen wir an, du willst viele Schritte im Commit-Baum zurückgehen. Dann wird es schnell mühsam immer wieder `^` einzugeben; deswegen gibt es in Git den Tilde-Operator `~`.", "", "Der Tilde-Operator akzeptiert optional eine Zahl, mit der du angeben kannst, wieviele Vorgänger du zurückgehen willst. Keine Anzahl anzugeben, bewirkt dasselbe wie `~1`." ] @@ -323,7 +471,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Geben wir mit `~` an wieviele Commits wir zurückgehen wollen" + "Geben wir mit `~` an, wieviele Commits wir zurückgehen wollen." ], "afterMarkdowns": [ "Peng! So einfach -- relative Referenzen sind super." @@ -340,11 +488,11 @@ exports.level = { "", "Du bist jetzt Experte in Sachen relative Referenzen, also lass sie uns mal richtig einsetzen.", "", - "Das Verschieben von Branches ist einer der häufigsten Anwendungsfälle dafür. Du kannst einen Branchnamen direkt auf einen bestimmten Commit setzen (_ohne_ ihne vorher ausgecheckt haben zu müssen!) indem du den Parameter `-f` benutzt. So in etwa:", + "Das Verschieben von Branches ist einer der häufigsten Anwendungsfälle dafür. Du kannst einen Branchnamen direkt auf einen bestimmten Commit setzen (_ohne_ ihn vorher ausgecheckt haben zu müssen!), indem du den Parameter `-f` benutzt. So in etwa:", "", - "`git branch -f master HEAD~3`", + "`git branch -f main HEAD~3`", "", - "Das bewegt (erzwungenermaßen) den `master` auf den Commit drei Vorgänger vor `HEAD`." + "Das bewegt (erzwungenermaßen) den `main` auf den Commit drei Vorgänger vor `HEAD`." ] } }, @@ -357,7 +505,7 @@ exports.level = { "afterMarkdowns": [ "Das war's schon! Relative Referenzen ermöglichen es uns den Commit `C1` sehr einfach anzugeben und `git branch -f` ermöglicht es uns, den Branch sehr schnell auf diesen Commit zu setzen." ], - "command": "git branch -f master HEAD~3", + "command": "git branch -f main HEAD~3", "beforeCommand": "git commit; git commit; git commit; git checkout -b bugFix" } }, @@ -367,7 +515,7 @@ exports.level = { "markdowns": [ "Jetzt wo du relative Referenzen und erzwungenes Branching in Kombination gesehen hast können wir damit den nächsten Level bewältigen.", "", - "Bewege `HEAD`, `master` und `bugFix` an die jeweils angegebenen Positionen, um diesen Level abzuschließen." + "Bewege `HEAD`, `main` und `bugFix` an die jeweils angegebenen Positionen, um diesen Level abzuschließen." ] } } @@ -411,9 +559,9 @@ exports.level = { "", "我使用相对引用最多的就是移动分支。可以直接使用 `-f` 选项让分支指向另一个提交。例如:", "", - "`git branch -f master HEAD~3`", + "`git branch -f main HEAD~3`", "", - "上面的命令会将 master 分支强制指向 HEAD 的第 3 级父提交。" + "上面的命令会将 main 分支强制指向 HEAD 的第 3 级父提交。" ] } }, @@ -426,7 +574,7 @@ exports.level = { "afterMarkdowns": [ "这就对了! 相对引用为我们提供了一种简洁的引用提交记录 `C1` 的方式, 而 `-f` 则容许我们将分支强制移动到那个位置。" ], - "command": "git branch -f master HEAD~3", + "command": "git branch -f main HEAD~3", "beforeCommand": "git commit; git commit; git commit; git checkout -b bugFix" } }, @@ -436,7 +584,7 @@ exports.level = { "markdowns": [ "既然你已经看过相对引用与强制移动分支的演示了,那么赶快使用这些技巧来挑战这一关吧!", "", - "要完成此关,移动 `HEAD`,`master` 和 `bugFix` 到目标所示的位置。" + "要完成此关,移动 `HEAD`,`main` 和 `bugFix` 到目标所示的位置。" ] } } @@ -480,9 +628,9 @@ exports.level = { "", "我使用相對引用最多的就是移動分支。你可以使用 `-f` 選項直接讓分支指向另一個 commit。舉個例子:", "", - "`git branch -f master HEAD~3`", + "`git branch -f main HEAD~3`", "", - "(強制)移動 master 指向從 HEAD 往上數的第三個 parent commit。" + "(強制)移動 main 指向從 HEAD 往上數的第三個 parent commit。" ] } }, @@ -490,7 +638,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "要完成這一關,移動 `HEAD`,`master` 和 `bugFix` 到目標所示的位置。" + "要完成這一關,移動 `HEAD`,`main` 和 `bugFix` 到目標所示的位置。" ] } } @@ -534,7 +682,7 @@ exports.level = { "", "相対リファレンスのよくある使い方としてあるのは、ブランチの移動です。`-f`オプションを使ってブランチを直接コミットに関連付けられます。次のようになります", "", - "`git branch -f master HEAD~3`", + "`git branch -f main HEAD~3`", "", "masterブランチを(強制的に)HEADより親三代前へと移動します。" ] @@ -549,7 +697,7 @@ exports.level = { "afterMarkdowns": [ "できました!相対リファレンスを使うことで、手短く`C1`を指定することができ、`-f`でブランチを強制的にそこへ移動することができました。" ], - "command": "git branch -f master HEAD~3", + "command": "git branch -f main HEAD~3", "beforeCommand": "git commit; git commit; git commit; git checkout -b bugFix" } }, @@ -559,7 +707,7 @@ exports.level = { "markdowns": [ "相対リファレンスとブランチの強制関連付けを見ましたので、いまここでそれらの方法を使ってみましょう。", "", - "このレベルをクリアするには`HEAD`、`master`、`bugFix`をゴールで指定されている目的位置まで移動してください。" + "このレベルをクリアするには`HEAD`、`main`、`bugFix`をゴールで指定されている目的位置まで移動してください。" ] } } @@ -603,9 +751,9 @@ exports.level = { "", "Одна из наиболее распространённых целей, для которых используются относительные ссылки - это перемещение веток. Можно напрямую прикрепить ветку к коммиту при помощи опции `-f`. Например, команда:", "", - "`git branch -f master HEAD~3`", + "`git branch -f main HEAD~3`", "", - "Переместит (принудительно) ветку `master` на три родителя назад от `HEAD`." + "Переместит (принудительно) ветку `main` на три родителя назад от `HEAD`." ] } }, @@ -618,7 +766,7 @@ exports.level = { "afterMarkdowns": [ "Вуаля! Относительная ссылка дала нам возможность просто сослаться на `C1`, а branch forcing (`-f`) позволил быстро переместить указатель ветки на этот коммит." ], - "command": "git branch -f master HEAD~3", + "command": "git branch -f main HEAD~3", "beforeCommand": "git commit; git commit; git commit; git checkout -b bugFix" } }, @@ -628,13 +776,13 @@ exports.level = { "markdowns": [ "Мы рассмотрели относительные ссылки и branch forcing вкупе, так что теперь пришло время пройти следующий уровень.", "", - "Чтобы пройти этот уровень, передвинь `HEAD`, `master` и `bugFix` так, как показано на визуализации." + "Чтобы пройти этот уровень, передвинь `HEAD`, `main` и `bugFix` так, как показано на визуализации." ] } } ] }, - "ko": { + "ko": { "childViews": [ { "type": "ModalAlert", @@ -672,9 +820,9 @@ exports.level = { "", "제가 상대 참조를 사용하는 가장 일반적인 방법은 브랜치를 옮길 때 입니다. `-f` 옵션을 이용해서 브랜치를 특정 커밋에 직접적으로 재지정 할 수 있습니다. 이런 식으로 말이죠:", "", - "`git branch -f master HEAD~3`", + "`git branch -f main HEAD~3`", "", - "(강제로) master 브랜치를 HEAD에서 세번 뒤로 옮겼습니다. (three parents behind HEAD)." + "(강제로) main 브랜치를 HEAD에서 세번 뒤로 옮겼습니다. (three parents behind HEAD)." ] } }, @@ -686,7 +834,7 @@ exports.level = { ], "afterMarkdowns": [ "됬네요! 우리는 상대 참조를 통해 `C1`을 간결한 방법으로 참조할 수 있었고 브랜치 강제(`-f`)를 통해 브랜치를 저 위치로 빠르게 옮길 수 있었습니다." ], - "command": "git branch -f master HEAD~3", + "command": "git branch -f main HEAD~3", "beforeCommand": "git commit; git commit; git commit; git checkout -b bugFix" } }, @@ -696,7 +844,7 @@ exports.level = { "markdowns": [ "자 이제 상대 참조와 브랜치 강제의 조합을 봤으니 다음 레벨을 해결해 봅시다.", "", - "이 레벨을 통과하기 위해서, `HEAD`와 `master`와 `bugFix`를 제시되는 골지점으로 옮겨 주십시오." + "이 레벨을 통과하기 위해서, `HEAD`와 `main`과 `bugFix`를 제시되는 골지점으로 옮겨 주십시오." ] } } @@ -740,9 +888,9 @@ exports.level = { "", "Один з найуживаніших прийомів де я використовую відносні посилання це переміщення гілок. Ти можеш напряму переспрямувати бранч на якийсь коміт використавши опцію `-f` (force, тобто насильно). Щось на зразок:", "", - "`git branch -f master HEAD~3`", + "`git branch -f main HEAD~3`", "", - "Переміщує (насильно) гілку master на три предки позад HEAD." + "Переміщує (насильно) гілку main на три предки позад HEAD." ] } }, @@ -755,7 +903,7 @@ exports.level = { "afterMarkdowns": [ "Ось і маєш! Відносні посилання дають нам зручний спосіб доступу до коміту`C1` крім того форсування бранчів (`-f`) дає нам можливість швидко перемістити гілку на цей коміт" ], - "command": "git branch -f master HEAD~3", + "command": "git branch -f main HEAD~3", "beforeCommand": "git commit; git commit; git commit; git checkout -b bugFix" } }, @@ -765,11 +913,218 @@ exports.level = { "markdowns": [ "Тепер, коли ти побачив відносні посилання та форсування гілок в купі, давай використаємо це щоб пройти поточний рівень.", "", - "Щоб пройти цей рівень, перемісти `HEAD`, `master` та `bugFix` так як показано в візуалізації." + "Щоб пройти цей рівень, перемісти `HEAD`, `main` та `bugFix` так як показано в візуалізації." ] } } ] - } + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Toán tử \"~\"", + "", + "Giả sử bạn muốn leo lên nhiều cấp trong git. Dùng `^` vài lần thì tù lắm, nên Git đã có dấu ngã (~) cho việc đó.", + "", + "", + "Theo sau toán tử ngã (~) là số lượng cha ông mà bạn muốn leo lên(không bắt buộc). Xem thử làm thật thì thế nào nào" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Hãy chỉ định số lượng commit với `~`." + ], + "afterMarkdowns": [ + "BÙUM! Quá chuẩn luôn -- tham chiếu tương đối tuyệt vời." + ], + "command": "git checkout HEAD~4", + "beforeCommand": "git commit; git commit; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Branch forcing", + "", + "Giờ thì bạn là cao thủ về tham chiếu tương đối rồi, *làm* thật thôi chứ nhỉ.", + "", + "Tôi thì hay thường dùng tham chiếu tương đối để dịch chuyển nhánh. Bạn có thể trực tiếp gán lại nhánh cho commit với cú pháp `-f`. Kiểu như thế này:", + "", + "`git branch -f main HEAD~3`", + "", + "dịch chuyển (ép buộc) nhánh main lên 3 commit phía trên HEAD." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Xem thử cái lệnh trên hoạt động sao nào." + ], + "afterMarkdowns": [ + "Đóóóó! Tham chiếu tương đối cho chúng ta một cách chuẩn xác để trỏ tới `C1` và ép nhánh bằng (`-f`) thì dịch chuyển nhanh chóng nhánh tới đó." + ], + "command": "git branch -f main HEAD~3", + "beforeCommand": "git commit; git commit; git commit; git checkout -b bugFix" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Giờ thì bạn đã thấy cách kết hợp tham chiếu tương đối và ép nhánh, dùng chúng để vượt level tiếp thôi.", + "", + "Để hoàn thành cấp độ này, chuyển `HEAD`, `main`, và `bugFix` đến mục tiêu được xác định của chúng." + ] + } + } + ] + }, + "sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Operator \"~\"", + "", + "Recimo, da se želiš premakniti veliko stopenj višje po drevesu commitov. Malo je nerodno večkrat tipkati `^`, zato ima Git tudi tilda (~) operator.", + "", + "", + "Tilda operator (opcijsko) sprejme številko, ki določi, koliko staršev bi se rad povzpel po drevesu. Poglejmo to v praksi." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Določimo število prejšnjih commitov z `~`." + ], + "afterMarkdowns": [ + "Boom! Tako jedrnato -- relativne reference so super." + ], + "command": "git checkout HEAD~4", + "beforeCommand": "git commit; git commit; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Forcanje Branchev", + "", + "Sedaj si strokovnjak za relativne reference, zato jih končno *uporabimo* za nekaj.", + "", + "Eden izmed najpogostejših načinov, kjer uporabljam relativne reference je za premikanje branchev naokoli. Direktno lahko premakneš branch na nek commit z `-f` opcijo. Takole nekako:", + "", + "`git branch -f main HEAD~3`", + "", + "premakne (s force-om) main branch tri commite za HEAD." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Poglejmo si prejšnji ukaz v praksi." + ], + "afterMarkdowns": [ + "Tako ja! Relativne reference so nam dale jedrnat način s katerim se lahko nanašamo na `C1` in branch force-anje (`-f`) nam je omogočilo, da hitro prestavimo branch na to lokacijo." + ], + "command": "git branch -f main HEAD~3", + "beforeCommand": "git commit; git commit; git commit; git checkout -b bugFix" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Sedaj ko smo si pogledali relativne reference in force branchanje v kombinaciji, uporabimo to, da rešimo naslednjo stopnjo.", + "", + "Za dokončanje te stopnje, premakni `HEAD`, `main` in `bugFix` na njihove ciljne prikazane destinacije." + ] + } + } + ] + }, + "pl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Operator \"~\"", + "", + "Powiedzmy, że chcesz przejść o wiele poziomów wstecz na drzewie commitów. Wielokrotne wpisywanie `^` może być męczące. Na tą okazję Git ma również operator - tyldę (~).", + "", + "", + "Operator tyldy (opcjonalnie) przyjmuje numer porządkowy, który określa liczbę rodziców o ile chcesz się wspiąć. Zobaczmy to w akcji." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Podajmy liczbę commitów, które chcemy przeskoczyć za `~`." + ], + "afterMarkdowns": [ + "Boom! Tak szybko - referencje względne są czadowe." + ], + "command": "git checkout HEAD~4", + "beforeCommand": "git commit; git commit; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Forsowanie branczy", + "", + "Jesteś teraz ekspertem ds. referencji. *Wykorzystajmy* je do czegoś.", + "", + "Jednym z najczęstszych sposobów, w jaki korzystam z referencji względnych, są działania na gałęziach. Możesz bezpośrednio przypisać gałąź do commita za pomocą opcji `-f`. Coś w tym stylu:", + "", + "`git branch -f main HEAD~3`", + "", + "przenosi (na siłę) gałąź `main` trzy commity wstecz za HEADa." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Sprawdźmy poprzednią komendę w akcji." + ], + "afterMarkdowns": [ + "Proszę bardzo! Referencje względne umożliwiły w zwięzły sposób, by odnieść się do `C1`, a forsowanie gałęzi (`-f`) pozwoliło na szybkie przeniesienie gałęzi w to konkretne miejsce." + ], + "command": "git branch -f main HEAD~3", + "beforeCommand": "git commit; git commit; git commit; git checkout -b bugFix" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Teraz, gdy poznałeś referencje względne i forsowanie gałęzi w połączeniu, użyj ich do rozwiązania następnego poziomu.", + "", + "Aby ukończyć ten poziom przenieś `HEAD`, `main` oraz `bugFix` do wyświetlonych celów." + ] + } + } + ] + }, } }; diff --git a/src/levels/rampup/reversingChanges.js b/src/levels/rampup/reversingChanges.js index 36e8f12d..d302741c 100644 --- a/src/levels/rampup/reversingChanges.js +++ b/src/levels/rampup/reversingChanges.js @@ -9,25 +9,35 @@ exports.level = { "ja" : "変更を元に戻す", "fr_FR": "Annuler des changements avec Git", "es_AR": "Revirtiendo cambios en git", + "es_ES": "Revirtiendo cambios en git", "pt_BR": "Revertendo mudanças no Git", - "ko": "Git에서 작업 되돌리기", + "gl" : "Revertindo cambios en git", + "ko" : "Git에서 작업 되돌리기", "zh_CN": "撤销变更", "zh_TW": "在 git 中取消修改 ", "ru_RU": "Отмена изменений в Git", - "uk": "Відміна змін в Git" + "uk": "Відміна змін в Git", + "vi": "Hoàn tác thay đổi trong Git", + "sl_SI": "Revertanje Sprememb v Gitu", + "pl": "Odwracanie zmian w Gitcie", }, "hint": { "en_US": "Notice that revert and reset take different arguments.", "de_DE": "Beachte, dass revert und reset unterschiedliche Argumente benötigen", "fr_FR": "Notez que `revert` et `reset` n'ont pas les mêmes arguments.", "es_AR": "Notá que revert y reset toman parámetros distintos", + "es_ES": "Observa que revert y reset utilizan parámetros distintos", "pt_BR": "Lembre que revert e reset recebem parâmetros diferentes", + "gl" : "Lembra que revert e reset usan parámetros distintos", "zh_CN": "注意 revert 和 reset 使用的参数不同。", "zh_TW": "注意 revert 和 reset 使用不同的參數。", "ko": "revert와 reset이 받는 인자가 다름을 기억하세요", "ja" : "revertとresetとで引数が異なることに注意。", "ru_RU": "Обрати внимание, что revert и reset принимают разные параметры.", - "uk": "Зверни увагу на те що revert та reset приймають різні параметри" + "uk": "Зверни увагу на те що revert та reset приймають різні параметри", + "vi": "Lưu ý rằng hoàn tác(revert) và đặt lại(reset) có những đối số khác nhau.", + "sl_SI": "Revert in reset sprejmeta različne argumente.", + "pl": "Zauważ, że revert i reset przyjmują różne argumenty", }, "startDialog": { "en_US": { @@ -56,7 +66,7 @@ exports.level = { "Let's see what that looks like:" ], "afterMarkdowns": [ - "Nice! Git moved the master branch reference back to `C1`; now our local repository is in a state as if `C2` had never happened." + "Nice! Git moved the main branch reference back to `C1`; now our local repository is in a state as if `C2` had never happened." ], "command": "git reset HEAD~1", "beforeCommand": "git commit" @@ -68,9 +78,9 @@ exports.level = { "beforeMarkdowns": [ "## Git Revert", "", - "While reseting works great for local branches on your own machine, its method of \"rewriting history\" doesn't work for remote branches that others are using.", + "While resetting works great for local branches on your own machine, its method of \"rewriting history\" doesn't work for remote branches that others are using.", "", - "In order to reverse changes and *share* those reversed changes with others, we need to use `git revert`. Let's see it in action" + "In order to reverse changes and *share* those reversed changes with others, we need to use `git revert`. Let's see it in action." ], "afterMarkdowns": [ "Weird, a new commit plopped down below the commit we wanted to reverse. That's because this new commit `C2'` introduces *changes* -- it just happens to introduce changes that exactly reverses the commit of `C2`.", @@ -119,7 +129,7 @@ exports.level = { "Veamos cómo es eso:" ], "afterMarkdowns": [ - "¡Genial! git simplemente movió la referencia de la rama master atrás hacia `C1`. Ahora tu repositorio local está en un estado como si `C2` nunca hubiera ocurrido" + "¡Genial! git simplemente movió la referencia de la rama main atrás hacia `C1`. Ahora tu repositorio local está en un estado como si `C2` nunca hubiera ocurrido." ], "command": "git reset HEAD~1", "beforeCommand": "git commit" @@ -156,6 +166,69 @@ exports.level = { } ] }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Revirtiendo cambios en git", + "", + "Hay varias maneras de revertir cambios en git. Y, tal como al commitear, revertir cambios en git tiene tanto un componente de bajo nivel (indexar archivos o fragmentos individualmente) como un componente de alto nivel (cómo son efectivamente revertidos los cambios). Nuestra aplicación se va a concentrar en esto último.", + "", + "Hay dos formas principales de deshacer cambios en git -- uno es usando `git reset` y el otro es usando `git revert`. Vamos a ver cada uno de ellos a continuación", + "" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "## Git Reset", + "", + "`git reset` deshace los cambios moviendo la referencia de una rama hacia atrás en el tiempo a un commit anterior. En este sentido puedes imaginarlo como \"reescribir la historia\". `git reset` va a mover la rama hacia atrás, como si el commit nunca se hubiera hecho.", + "", + "Veamos cómo es eso:" + ], + "afterMarkdowns": [ + "¡Genial! git simplemente movió la referencia de la rama main atrás hacia `C1`. Ahora tu repositorio local está en un estado como si `C2` nunca hubiera ocurrido." + ], + "command": "git reset HEAD~1", + "beforeCommand": "git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "## Git Revert", + "", + "Mientras que resetear los cambios funciona estupendamente para ramas locales en tu máquina, su método de \"reescribir la historia\" no funciona para ramas remotas que otros están usando.", + "", + "Para revertir cambios y *compartir* esa _revertida_ con otros, necesitamos usar `git revert`. Veámoslo en acción" + ], + "afterMarkdowns": [ + "Extraño. Hay un nuevo commit aplicado sobre el que queríamos revertir. Eso es porque este nuevo commit `C2'` introduce *cambios* - sólo que esos cambios son exactamente los necesarios para revertir los que introdujo `C2`.", + "", + "Cuando utilices revert, puedes hacer push sobre ese cambio para compartirlo con otros." + ], + "command": "git revert HEAD", + "beforeCommand": "git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para completar este nivel, deshaz los dos commits más recientes, tanto en `local` como en `pushed`.", + "", + "Ten en cuenta que `pushed` es una rama remota y `local` es una rama local -- eso debería ayudarte a elegir qué métodos usar." + ] + } + } + ] + }, "pt_BR": { "childViews": [ { @@ -182,7 +255,7 @@ exports.level = { "Vejamos como funciona:" ], "afterMarkdowns": [ - "Legal! O Git simplesmente moveu a referência do ramo master de volta para `C1`; agora o nosso repositório local está em um estado como se o `C2` nunca tivesse acontecido" + "Legal! O Git simplesmente moveu a referência do ramo main de volta para `C1`; agora o nosso repositório local está em um estado como se o `C2` nunca tivesse acontecido." ], "command": "git reset HEAD~1", "beforeCommand": "git commit" @@ -219,17 +292,17 @@ exports.level = { } ] }, - "de_DE": { + "gl": { "childViews": [ { "type": "ModalAlert", "options": { "markdowns": [ - "## Änderungen in Git rückgängig machen", + "## Revertindo cambios en Git", "", - "Es gibt viele Möglichkeiten, Änderungen in Git zurückzunehmen. Und ebenso wie das Committen hat auch das rückgängig Machen eine Basis-Komponente (Dateien und Inhalte vormerken) und einen übergeordneten Aspekt (wie die Änderungen tatsächlich zurückgenommen werden). Diese Applikation beschäftigt sich wiederum mit den übergeordneten Vorgängen.", + "Existen varias formas de revertir os cambios en git. E, como cando se fai commit, desfacer cambios supon unha operación de baixo nivel (a indexación de arquivos ou trozos de eles) e unha operación de alto nivel (desfacer os cambios xa aplicados). Aquí ímonos enfocar neste último punto.", "", - "Es gibt grundsätzlich zwei Arten in Git etwas rückgängig zu machen -- einerseits `git reset` und andererseit `git revert`. Wir schauen uns beide mal an.", + "Hai dúas formas de desfacer os cambios en git -- unha delas é `git reset`, e a outra é usando `git revert`. Imos comparalas na próxima ventá.", "" ] } @@ -240,12 +313,75 @@ exports.level = { "beforeMarkdowns": [ "## Git Reset", "", - "`git reset` nimm Änderungen zurück, indem es eine Branch-Referenz auf einen anderen Commit setzt. Es ist ein bisschen (aber nicht wirklich) wie \"Geschichte umschreiben\"; `git reset` bewegt einen Branch auf einen anderen Commit, als hätte er nie anders ausgesehen.", + "O comando `git reset` desfai os cambios movendo a referencia dunha rama cara un commit máis antigo na rama. Desta forma, podes pensar nesta operación como \"reescritura do histórico\"; o `git reset` vai movela rama cara atrás, como se ós commits nunca antes se fixeran.", + "", + "Vexamos o seu funcionamento:" + ], + "afterMarkdowns": [ + "¡Bye bye! Git moveu a referencia da rama main cara atrás, ata o commit `C1`; agora o teu repositorio local está coma se o commit `C2` nunca acontecera." + ], + "command": "git reset HEAD~1", + "beforeCommand": "git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "## Git Revert", + "", + "Mentres que resetear os cambios funciona xenial para as ramas locales na túa máquina, o método utilizado de \"reescribir o histórico\" non funciona con ramas remotas que outra xente usa.", + "", + "Para revervir os cambios e *compartir* eses cambios ca outra xente, precisamos usar `git revert`. Atende a cómo funciona." + ], + "afterMarkdowns": [ + "Estrano, xurdíu un novo commit por baixo do commit que queriamos desfacer. Iso é porque o novo commit `C2'` engadíu *cambios* -- o que pasa é que o commit desfai exactamente os cambios feitos no commit `C2`.", + "", + "Con `revert`, ti podes facer `push` dos teus cambios para compartilos cos outros." + ], + "command": "git revert HEAD", + "beforeCommand": "git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para completar este nivel, reverte os dous commits máis recentes tanto en `local` como en `pushed`.", + "", + "Ten en mente que `pushed` é unha rama remota, e `local` é unha rama local -- Iso poida que te axude a aplicar o método apropriado." + ] + } + } + ] + }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Änderungen in Git rückgängig machen", + "", + "Es gibt viele Möglichkeiten, Änderungen in Git zurückzunehmen. Und ebenso wie das Committen hat auch das rückgängig Machen eine Basis-Komponente (Dateien und Inhalte vormerken) und einen übergeordneten Aspekt (wie die Änderungen tatsächlich zurückgenommen werden). Dieses Level beschäftigt sich mit den übergeordneten Vorgängen.", + "", + "Es gibt grundsätzlich zwei Arten in Git etwas rückgängig zu machen -- einerseits `git reset` und andererseits `git revert`. Wir schauen uns beide mal an.", + "" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "## Git Reset", + "", + "`git reset` nimmt Änderungen zurück, indem es eine Branch-Referenz auf einen anderen Commit setzt. Es ist ein bisschen (aber nicht wirklich) wie \"Geschichte umschreiben\"; `git reset` bewegt einen Branch auf einen anderen Commit, als hätte er nie anders ausgesehen.", "", "Schauen wir, wie das aussieht:" ], "afterMarkdowns": [ - "Schick! Git hat den `master` einfach auf `C1` gesetzt; unser lokales Repository sieht nun so aus, als hätte `C2` nie stattgefunden." + "Schick! Git hat den `main` einfach auf `C1` gesetzt; unser lokales Repository sieht nun so aus, als hätte `C2` nie stattgefunden." ], "command": "git reset HEAD~1", "beforeCommand": "git commit" @@ -353,7 +489,7 @@ exports.level = { "markdowns": [ "## Annuler des changements avec Git", "", - "Il y a de nombreuses façons d'annuler des changement avec Git. De même que pour les commits, annuler des changements avec Git est à la fois un aspect bas-niveau (gestion des fichiers et morceaux de fichiers) et un aspect de plus haut niveau (comment les changements sont effectivement annulés). Nous allons nous intéresser à ce dernier point.", + "Il y a de nombreuses façons d'annuler des changements avec Git. De même que pour les commits, annuler des changements avec Git est à la fois un aspect bas-niveau (gestion des fichiers et morceaux de fichiers) et un aspect de plus haut niveau (comment les changements sont effectivement annulés). Nous allons nous intéresser à ce dernier point.", "", "Il y a principalement deux façons d'annuler des changements avec Git : l'une est `git reset` et l'autre est `git revert`. Nous allons maintenant voir chacune de ces façons.", "" @@ -371,7 +507,7 @@ exports.level = { "Regardons à quoi cela ressemble :" ], "afterMarkdowns": [ - "Bravo ! Git a simplement déplacé la référence de la branche master en la faisant revenir sur `C1`; désormais notre dépôt est dans le même état que si `C2` n'avait jamais eu lieu" + "Bravo ! Git a simplement déplacé la référence de la branche main en la faisant revenir sur `C1`; désormais notre dépôt est dans le même état que si `C2` n'avait jamais eu lieu." ], "command": "git reset HEAD~1", "beforeCommand": "git commit" @@ -385,7 +521,7 @@ exports.level = { "", "Bien que le reset marche parfaitement pour les branches locales sur notre propre machine, cette façon de \"réécrire l'histoire\" ne marche pas avec les banches distantes (remote) que d'autres personnes utilisent.", "", - "Pour pouvoir annuler des changements et *partager* ces annulations avec d'autres, nous devons utiliser `git revert`. Regardons comment cela fonctionne" + "Pour pouvoir annuler des changements et *partager* ces annulations avec d'autres, nous devons utiliser `git revert`. Regardons comment cela fonctionne." ], "afterMarkdowns": [ "Étrangement, un nouveau commit est apparu en bas sous le commit que nous voulions annuler. C'est parce que ce nouveau commit `C2'` introduit des *modifications* -- celles qui correspondent justement à l'annulation de celles du commit `C2`.", @@ -400,7 +536,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Pour accomplir ce niveau, annulez les deux derniers commits à la fois sur `local` et sur `pushed`.", + "Pour accomplir ce niveau, annulez les derniers commits à la fois sur `local` et sur `pushed`. Vous devez annuler en tout 2 commits (un pour chaque branche).", "", "Ayez à l'esprit que `pushed` est une branche distante et `local` est une branche locale ; cela devrait vous guider dans le choix de la méthode à employer." ] @@ -435,7 +571,7 @@ exports.level = { ], "command": "git reset HEAD~1", "afterMarkdowns": [ - "漂亮! Git 把 master 分支移回到 `C1`;现在我们的本地代码库根本就不知道有 `C2` 这个提交了。", + "漂亮! Git 把 main 分支移回到 `C1`;现在我们的本地代码库根本就不知道有 `C2` 这个提交了。", "", "(译者注:在reset后, `C2` 所做的变更还在,但是处于未加入暂存区状态。)" ], @@ -500,7 +636,7 @@ exports.level = { ], "command": "git reset HEAD~1", "afterMarkdowns": [ - "太好了! Git 把 master branch 簡單地移回到 `C1`;現在在我們的 local 已經退回到沒有 commit 過 `C2` 的狀態了。" + "太好了! Git 把 main branch 簡單地移回到 `C1`;現在在我們的 local 已經退回到沒有 commit 過 `C2` 的狀態了。" ], "beforeCommand": "git commit" } @@ -562,7 +698,7 @@ exports.level = { "어떤 그림인지 한번 보죠:" ], "afterMarkdowns": [ - "그림에서처럼 master 브랜치가 가리키던 커밋을 `C1`로 다시 옮겼습니다; 이러면 로컬 저장소에는 마치 `C2`커밋이 아예 없었던 것과 마찬가지 상태가 됩니다." + "그림에서처럼 main 브랜치가 가리키던 커밋을 `C1`로 다시 옮겼습니다; 이러면 로컬 저장소에는 마치 `C2`커밋이 아예 없었던 것과 마찬가지 상태가 됩니다." ], "command": "git reset HEAD~1", "beforeCommand": "git commit" @@ -625,7 +761,7 @@ exports.level = { "Посмотрим, как это работает:" ], "afterMarkdowns": [ - "Неплохо! Git просто перенёс ссылку на `master` обратно на коммит `C1`. Теперь наш локальный репозиторий в состоянии, как будто `C2` никогда не существовал." + "Неплохо! Git просто перенёс ссылку на `main` обратно на коммит `C1`. Теперь наш локальный репозиторий в состоянии, как будто `C2` никогда не существовал." ], "command": "git reset HEAD~1", "beforeCommand": "git commit" @@ -688,7 +824,7 @@ exports.level = { "Давайте подивимося, як це виглядає:" ], "afterMarkdowns": [ - "Чудово! Git перемістив посилання гілки master назад до `C1`; тепер наш локальний репозиторій в такому стані, наче коміту `C2` ніколи не було." + "Чудово! Git перемістив посилання гілки main назад до `C1`; тепер наш локальний репозиторій в такому стані, наче коміту `C2` ніколи не було." ], "command": "git reset HEAD~1", "beforeCommand": "git commit" @@ -724,6 +860,185 @@ exports.level = { } } ] + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Hoàn tác trong Git", + "", + "Có rất nhiều cách để hoàn tác thay đổi trong Git. Và cũng tương tự như commit, hủy thay đổi trong Git có cả thành phần bậc thấp (tạm thời lưu trữ một số tệp hoặc đoạn độc lập) và thành phần bậc cao (cách mà các thay đổi thực sự bị hủy). Ứng dụng của chúng tôi tập trung vào cái sau.", + "", + "Có 2 cách nguyên thủy để hủy thay đổi trong Git -- một là dùng `git reset` và cách khác là dùng `git revert`. Chúng ta sẽ xem xét từng cái trong hội thoại sau", + "" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "## Git Reset", + "", + "`git reset` hoàn tác bằng cách chuyển tham chiếu của nhánh ngược lên commit cũ hơn. Bạn có thể hiểu nó như kiểu \"viết lại lịch sử;\" `git reset` sẽ dịch chuyển nhánh lên trên như thể commit chưa bao giờ được tạo ra vậy.", + "", + "Cùng xem thử nó trông thế nào nào:" + ], + "afterMarkdowns": [ + "Hay! Git chuyển tham chiếu của main trở lại `C1`; bây giờ kho cá nhân của ta trông như thể commit `C2` chưa bao giờ xảy ra vậy." + ], + "command": "git reset HEAD~1", + "beforeCommand": "git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "## Git Revert", + "", + "Trong khi git reset hoạt động rất tốt tại nhánh cục bộ trên máy cá nhân, cách thức \"viết lại lịch sử\" chẳng hề có tác dụng lên nhánh ở phương xa mà người khác sử dụng.", + "", + "Để có thể hoàn tác và *chia sẻ* hoàn tác đó với người khác, thì ta cần sử dụng `git revert`. Xem thử cách thức nó hoạt động nào" + ], + "afterMarkdowns": [ + "Lạ nhỉ, một commit mới được thả vào bên dưới commit mà ta muốn hoàn tác. Đó là bởi vì commit mới `C2'` này có chứa *thay đổi* -- đó là những thay đổi về hoàn tác commit `C2`.", + "", + "Dùng revert thì bạn có thể đẩy thay đổi mình lên và chia sẻ với người khác." + ], + "command": "git revert HEAD", + "beforeCommand": "git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Để hoàn thành cấp độ này, hoàn tác commit gần nhất trên cả `local` (`cục bộ`) và `pushed` (`được đẩy`). Bạn sẽ hoàn tác tổng cộng 2 commit(một trên mỗi nhánh).", + "", + "Nhớ rằng `pushed` là nhánh ở phương xa và `local` là nhánh địa phương -- như thế thì bạn sẽ chọn được phương án phù hợp." + ] + } + } + ] + }, + "sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Revertanje Sprememb v Gitu", + "", + "Veliko načinov je, kako revertati (razveljaviti) spremembe v Gitu. In tako kot commitanje ima tudi revertanje sprememb v Gitu low-level komponente (stageanje posameznih datotek ali kosov) in high-level komponente (kako so spremembe dejansko povrnjene). Naša aplikacija se bo osredotočila na slednje.", + "", + "Obstajata dva glavna načina kako razveljaviti spremembe v Gitu -- prvi je uporaba `git reset` in drugi je uporaba `git revert`. V naslednjem dialogu si bomo pogledali oba pristopa.", + "" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "## Git Reset", + "", + "`git reset` povrne spremembe tako, da prestavi referenco brancha na starejši commit. Lahko si predstavljaš kot \"pisanje zgodovine na novo\"; `git reset` bo prestavil branch nazaj, kot da se commiti sploh niso zgodili.", + "", + "Poglejmo kako to izgleda:" + ], + "afterMarkdowns": [ + "Lepo! Git je premaknil main branch referenco nazaj na `C1`; sedaj je naš lokalen repozitorij v stanju, kot da se `C2` sploh ni nikoli zgodil." + ], + "command": "git reset HEAD~1", + "beforeCommand": "git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "## Git Revert", + "", + "Medtem ko ponastavljanje z reset deluje super na lokalnih brancih na tvoji mašini, njegova metoda \"prepisovanja zgodovina\" ne deluje na remote brancih, ki jih uporabljajo drugi.", + "", + "Če želimo ponastaviti spremembe in *deliti* te ponastavitve z drugimi, moramo uporabiti `git revert`. Poglejmo si to v praksi." + ], + "afterMarkdowns": [ + "Čudno, nov commit se je naredil pod commitom, ki smo ga želeli reversati. To je zato, ker ta nov commit `C2'` uvede *spremembe* -- spremembe so pač v tem primeru točno nasprotne od `C2`.", + "", + "Z revertanjem lahko pushas in deliš svoje spremembe tudi z drugimi." + ], + "command": "git revert HEAD", + "beforeCommand": "git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Za dokončanje te stopnje, povrni oba zadnja commita, tako na `local` kot na `pushed` brancih. Skupno boš revertal dva commita (enega na branch).", + "", + "Upoštevaj, da je `pushed` oddaljen branch in `local` lokalen branch -- to bi ti moralo pomagati izbrati metodo." + ] + } + } + ] + }, + "pl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Odwracanie zmian w Gitcie", + "", + "Istnieje wiele sposobów na odwrócenie zmian w Gicie. Podobnie jak w przypadku commitowania, odwracanie zmian w Gitcie ma zarówno komponent niskopoziomowy (zapisywanie stanów plików lub ich fragmentów), jak i wysokopoziomowy (sposób, w jaki zmiany są faktycznie odwracane). Nasza aplikacja skupi się na tym ostatnim.", + "", + "Istnieją dwa podstawowe sposoby na cofnięcie zmian w Gicie - jeden z nich to `git reset`, a drugi `git revert`. Przyjrzymy się każdemu z nich w następnym oknie", + "" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "## Git Reset", + "", + "`git reset` odwraca zmiany poprzez przesunięcie referencji gałęzi wstecz w czasie do starszego commita. Można myśleć o tym jako \"przepisywaniu historii\", \"resetowanie\" spowoduje cofnięcie gałęzi do tyłu, tak jakby commity powyżej nigdy nie zostały dodane.", + "", + "Sprawdźmy jak to działa:" + ], + "afterMarkdowns": [ + "Świetnie! Git przeniósł referencję gałęzi `main` do `C1`; teraz nasze lokalne repozytoriu jest w stanie, jakby commit `C2` nigdy nie powstał." + ], + "command": "git reset HEAD~1", + "beforeCommand": "git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "## Git Revert", + "", + "Podczas gdy resetowanie działa świetnie dla lokalnych gałęzi na własnej maszynie, jego metoda \"przepisywania historii\" nie działa dla gałęzi zdalnych, które są używane przez innych.", + "", + "W celu odwrócenia zmian i *podzielenia się* tymi odwróconymi zmianami z innymi, musimy użyć `git revert`. Zobaczmy to w akcji." + ], + "afterMarkdowns": [ + "Dziwne, nowy commit spadł poniżej zobowiązania, które chcieliśmy odwrócić. To dlatego, że to nowy commit `C2'` wprowadza *zmiany* -- tak się składa, że wprowadza zmiany, które idealnie odwracają commit `C2`.", + "", + "Dzięki `git revert`, możesz wypchnąć swoje zmiany, by podzielić się nimi z innymi." + ], + "command": "git revert HEAD", + "beforeCommand": "git commit" + } + }, + ] } } }; diff --git a/src/levels/rebase/manyRebases.js b/src/levels/rebase/manyRebases.js index dd99b175..4c38cd61 100644 --- a/src/levels/rebase/manyRebases.js +++ b/src/levels/rebase/manyRebases.js @@ -5,33 +5,43 @@ exports.level = { "git cherry-pick": true }, "goalTreeString": "%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C7%27%22%2C%22id%22%3A%22master%22%7D%2C%22bugFix%22%3A%7B%22target%22%3A%22C3%27%22%2C%22id%22%3A%22bugFix%22%7D%2C%22side%22%3A%7B%22target%22%3A%22C6%27%22%2C%22id%22%3A%22side%22%7D%2C%22another%22%3A%7B%22target%22%3A%22C7%27%22%2C%22id%22%3A%22another%22%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C4%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C4%22%7D%2C%22C5%22%3A%7B%22parents%22%3A%5B%22C4%22%5D%2C%22id%22%3A%22C5%22%7D%2C%22C6%22%3A%7B%22parents%22%3A%5B%22C5%22%5D%2C%22id%22%3A%22C6%22%7D%2C%22C7%22%3A%7B%22parents%22%3A%5B%22C5%22%5D%2C%22id%22%3A%22C7%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%27%22%7D%2C%22C4%27%22%3A%7B%22parents%22%3A%5B%22C3%27%22%5D%2C%22id%22%3A%22C4%27%22%7D%2C%22C5%27%22%3A%7B%22parents%22%3A%5B%22C4%27%22%5D%2C%22id%22%3A%22C5%27%22%7D%2C%22C6%27%22%3A%7B%22parents%22%3A%5B%22C5%27%22%5D%2C%22id%22%3A%22C6%27%22%7D%2C%22C7%27%22%3A%7B%22parents%22%3A%5B%22C6%27%22%5D%2C%22id%22%3A%22C7%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%7D", - "solutionCommand": "git rebase master bugFix;git rebase bugFix side;git rebase side another;git rebase another master", + "solutionCommand": "git rebase main bugFix;git rebase bugFix side;git rebase side another;git rebase another main", "startTree": "{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\"},\"bugFix\":{\"target\":\"C3\",\"id\":\"bugFix\"},\"side\":{\"target\":\"C6\",\"id\":\"side\"},\"another\":{\"target\":\"C7\",\"id\":\"another\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C0\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C4\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C5\"],\"id\":\"C6\"},\"C7\":{\"parents\":[\"C5\"],\"id\":\"C7\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}", "name": { "en_US": "Rebasing over 9000 times", "de_DE": "10000 Rebases unter dem `HEAD`", "es_AR": "Rebaseando más de 9000 veces", + "es_ES": "Rebaseando más de 9000 veces", "pt_BR": "Fazendo mais de 9000 rebases", + "gl" : "Facendo máis de 9000 rebases", "fr_FR": "Rebaser plus de 1000 fois", "ko": "9천번이 넘는 리베이스", "ja" : "9000回以上のrebase", "zh_CN": "多次 Rebase", "zh_TW": "N次Rebase", "ru_RU": "Rebase over 9000 раз", - "uk" : "Rebase over 9000 разів" + "uk" : "Rebase over 9000 разів", + "vi" : "Rebase hơn 9000 lần", + "sl_SI": "Več kot 9000 Rebaseov", + "pl" : "Ponad 9000 podbić" }, "hint": { - "en_US": "Remember, the most efficient way might be to only update master at the end...", - "de_DE": "Nicht vergessen: die effizienteste Möglichkeit könnte sein, schließlich einfach nur den master zu aktualisieren ...", - "es_AR": "Acordate, la manera más eficiente podría ser actualizar master sólo al final...", - "pt_BR": "Lembre-se, a forma mais eficiente pode ser atualizar o master por último...", - "fr_FR": "Rappelez-vous, la façon la plus efficace peut être de mettre à jour master seulement à la fin ...", + "en_US": "Remember, the most efficient way might be to only update main at the end...", + "de_DE": "Nicht vergessen: nur den main zu aktualisieren könnte die effizienteste Möglichkeit sein ...", + "es_AR": "Acordate, la manera más eficiente podría ser actualizar main sólo al final...", + "es_ES": "Recuerda, la manera más eficiente podría ser actualizar main sólo al final...", + "pt_BR": "Lembre-se, a forma mais eficiente pode ser atualizar o main por último...", + "gl" : "Lembra, a forma máis eficiente pode ser actualizar a rama main ó final...", + "fr_FR": "Rappelez-vous, la façon la plus efficace peut être de mettre à jour main seulement à la fin ...", "ja" : "最も効率的なやり方はmasterを最後に更新するだけかもしれない・・・", - "ko": "아마도 master를 마지막에 업데이트하는 것이 가장 효율적인 방법일 것입니다...", - "zh_CN": "记住,最后更新 master 分支可能是最高效的方法……", - "zh_TW": "要記住喔! 把 master branch 留到最後更新可能是最有效率的方法。", + "ko": "아마도 main을 마지막에 업데이트하는 것이 가장 효율적인 방법일 것입니다...", + "zh_CN": "记住,最后更新 main 分支可能是最高效的方法……", + "zh_TW": "要記住喔! 把 main branch 留到最後更新可能是最有效率的方法。", "ru_RU": "Не забудь, что лучше всего сдвинуть мастер в самом конце...", - "uk" : "Не забувай, що краще всього буде перемістити master в самому кінці... " + "uk" : "Не забувай, що краще всього буде перемістити main в самому кінці... ", + "vi" : "Hãy nhớ rằng, cách tốt nhất có lẽ là nên cuối cùng mới cập nhật nhánh `main`... ", + "sl_SI": "Pomni, morda je najbolj učinkovit način posodabljanje masterja samo na koncu ...", + "pl" : "Pamiętaj, że najskuteczniejszym sposobem może być aktualizacja `main` na końcu..." }, "startDialog": { "en_US": { @@ -42,7 +52,7 @@ exports.level = { "markdowns": [ "### Rebasing Multiple Branches", "", - "Man, we have a lot of branches going on here! Let's rebase all the work from these branches onto master.", + "Man, we have a lot of branches going on here! Let's rebase all the work from these branches onto main.", "", "Upper management is making this a bit trickier though -- they want the commits to all be in sequential order. So this means that our final tree should have `C7'` at the bottom, `C6'` above that, and so on, all in order.", "", @@ -60,7 +70,7 @@ exports.level = { "markdowns": [ "### Rebaseando múltiples ramas", "", - "Man, ¡hay un montón de ramas acá! Rebaseemos todo el trabajo de esas ramas sobre master.", + "Man, ¡hay un montón de ramas acá! Rebaseemos todo el trabajo de esas ramas sobre main.", "", "La gente de administración nos está haciendo las cosas un poco complicadas, igual -- quieren que nuestros commits estén todos en orden secuencial. Esto significa que nuestro árbol final tendría que tener `C7` al final, `C6` antes de ese, y así siguiendo, todos en orden.", "", @@ -70,6 +80,24 @@ exports.level = { } ] }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Rebaseando múltiples ramas", + "", + "Fíjate, ¡hay un montón de ramas aquí! Rebaseemos todo el trabajo de esas ramas sobre main.", + "", + "La gente de administración nos está haciendo las cosas un poco complicadas, igual -- quieren que nuestros commits estén todos en orden secuencial. Esto significa que nuestro árbol final tendría que tener `C7` al final, `C6` antes de ese, y así siguiendo, todos en orden.", + "", + "Si te haces un lío durante el proceso, siéntete libre de usar `reset` para empezar de nuevo. ¡Asegúrate de verificar tu solución y ver si puedes realizarla en un número inferior de commandos!" + ] + } + } + ] + }, "pt_BR": { "childViews": [ { @@ -78,7 +106,7 @@ exports.level = { "markdowns": [ "### Fazendo rebase em múltiplos ramos", "", - "Cara, temos um monte de ramos aqui! Vamos fazer um rebase de todo o trabalho contido nesses ramos para o master.", + "Cara, temos um monte de ramos aqui! Vamos fazer um rebase de todo o trabalho contido nesses ramos para o main.", "", "No entanto, a cúpula da administração está tornando as coisas mais difíceis -- eles querem que os commits estejam todos em ordem sequencial. Isso significa que a nossa árvore final precisa ter o `C7'` por último, `C6'` acima disso, e assim por diante, tudo ordenado.", "", @@ -88,6 +116,24 @@ exports.level = { } ] }, + "gl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Fazendo rebase en múltiples ramas", + "", + "Neno, temos unha chea de ramas aquí! Imos facer rebase de todo o traballo contido nesas ramas para a main.", + "", + "A xente de administración estanos a facer as cousas complicadas, igual eles queren que os commits estén todos en orde secuencial. Isto significa que a nosa árbore final precisa ter `C7'` de último, `C6'` inda por riba, está por adiante, todo ordeado.", + "", + "Se te fas un lio polo camiño, síntete ceibe para usar o comando `reset` para comezar de cero outra vez. Despois lembra ollar a nosa solución para ver se consegues resolver a tarefa usando menos comandos!" + ] + } + } + ] + }, "fr_FR": { "childViews": [ { @@ -96,7 +142,7 @@ exports.level = { "markdowns": [ "### Rebaser plusieurs branches", "", - "Dis-donc, nous avons beaucoup de branches par ici ! Rebasons tout le travail de ces branches dans master.", + "Dis-donc, nous avons beaucoup de branches par ici ! Rebasons tout le travail de ces branches dans main.", "", "Les patrons rendent cela encore plus compliqué -- ils veulent que les commits soient fait de manière séquentielle. Cela signifie donc que dans votre arbre final `C7'` est tout en bas, `C6'` juste au-dessus, et ainsi de suite, tout dans cet ordre.", "", @@ -114,11 +160,11 @@ exports.level = { "markdowns": [ "### Mehrere Branches rebasen", "", - "Wow, wir haben hier ja eine Menge Branches! Lass uns mal die ganze Arbeit, die in diesen Branches steckt, auf den `master` packen, um sie auf Stand zu bringen.", + "Wow, wir haben hier ja eine Menge Branches! Lass uns mal die ganze Arbeit, die in diesen Branches steckt, auf den `main` packen, um sie auf Stand zu bringen.", "", - "Die Führungsetage macht die Sache allerdings etwas trickreicher -- die möchten, dass alle Commits in aufsteigender Reihenfolge geordnet sind. Das heißt unser fertiger Baum sollte `C7` ganz unten haben, darüber `C6` und so weiter und so fort.", + "Die Führungsetage macht die Sache allerdings etwas trickreicher -- sie möchte, dass alle Commits in aufsteigender Reihenfolge geordnet sind. Das heißt unser fertiger Baum sollte `C7` ganz unten haben, darüber `C6` und so weiter und so fort.", "", - "Wenn du irgendwo einen Fehler machst, benütze ruhig `reset` um wieder von vorne anzufangen oder `undo` um einen Schritt zurückzugehen. Schau dir die Lösung an und versuch es in weniger Schritten hinzubekommen." + "Wenn du irgendwo einen Fehler machst, benütze ruhig `reset` um wieder von vorne anzufangen oder `undo` um einen Schritt zurückzugehen. Schau dir die Lösung an und versuche es in weniger Schritten hinzubekommen." ] } } @@ -150,7 +196,7 @@ exports.level = { "markdowns": [ "### 多分支 rebase", "", - "哥们儿,我们准备了很多分支!咱们把这些分支 rebase 到 master 上吧。", + "哥们儿,我们准备了很多分支!咱们把这些分支 rebase 到 main 上吧。", "", "但是你的领导给你提了点要求 —— 他们希望得到有序的提交历史,也就是我们最终的结果应该是 `C6'` 在 `C7'` 上面, `C5'` 在 `C6'` 上面,依此类推。", "", @@ -168,7 +214,7 @@ exports.level = { "markdowns": [ "### rebase 多個 branch", "", - "嗨!現在我們有很多 branch 了啦!讓我們做一下 rebase,將這些分支接到 master branch 上吧。", + "嗨!現在我們有很多 branch 了啦!讓我們做一下 rebase,將這些分支接到 main branch 上吧。", "", "但是你的主管找了點麻煩,他們希望得到有序的 commit history,也就是我們最終的結果是 `C7'` 在最下面,`C6'` 在它上面,以此類推。", "", @@ -186,7 +232,7 @@ exports.level = { "markdowns": [ "### 여러 브랜치를 리베이스(rebase)하기 ", "", - "음, 여기 꽤 여러개의 브랜치가 있습니다! 이 브랜치들의 모든 작업내역을 master에 리베이스 해볼까요?", + "음, 여기 꽤 여러개의 브랜치가 있습니다! 이 브랜치들의 모든 작업내역을 `main` 브랜치에 리베이스 해볼까요?", "", "윗선에서 일을 복잡하게 만드네요 -- 그 분들이 이 모든 커밋들을 순서에 맞게 정렬하라고 합니다. 그럼 결국 우리의 최종 목표 트리는 제일 아래에 `C7'` 커밋, 그 위에 `C6'` 커밋, 또 그 위에 순서대로 보여합니다.", "", @@ -222,7 +268,7 @@ exports.level = { "markdowns": [ "### Ребейсимо кілька гілок", "", - "В нас тут до біса гілок! Перенесімо всі зміни з різних гілок в master.", + "В нас тут до біса гілок! Перенесімо всі зміни з різних гілок в main.", "", "Але вище керівництво нам не полегшує життя -- вони хочуть, щоб всі коміти були впорядковані. Це означає, що в результаті коміт `C7'` має бути з самого низу, `C6'` трохи вище, і так далі, все за порядком.", "", @@ -231,6 +277,41 @@ exports.level = { } } ] + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Rebase nhiều nhánh", + "", + "Giời ạ, sao mà nhiều nhánh thế khôn biết! Chuyển hết chúng vào `main` thôi.", + "", + "Nhưng mà cha quản lý lại muốn oái oăm hơn cơ -- hắn muốn tất cả commit xếp thẳng hàng. Nghĩa là cây lịch sử của ta sẽ có `C7'` ở cuối, phía trên là`C6'`, và cứ thế theo đúng thứ tự.", + "", + "Nếu mà nhỡ may bạn làm nhầm thì có thể dùng lệnh `reset` để bắt đầu lại. Hãy nhớ đối chiếu với đáp án của chúng tôi xem bạn có thể hoàn thành với ít câu lệnh hơn không!" + ] + } + } + ] + },"sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Rebasing Večih Branchev", + "", + "Uf, tu imamo pa res veliko branchev! Pojdimo in rebaseajmo vse delo iz teh branchev na main.", + "", + "Toda vodstvo se je odločilo, da le ne bo tako preprosto -- žeijo da so vsi commiti v zaporednem vrstnem redu. To pomeni, da bo naše ciljno drevo moralo imeti `C7'` na dnu, `C6'` nad njim, in tako dalje po vrsti.", + "", + "Če med reševanjem zamočiš, preprosto uporabi `reset`, da začneš znova. Poglej tudi našo rešitev in preveri, če lahko stopnjo rešiš še z manj ukazi!" + ] + } + } + ] } } }; diff --git a/src/levels/rebase/selectiveRebase.js b/src/levels/rebase/selectiveRebase.js index f337a353..01175c26 100644 --- a/src/levels/rebase/selectiveRebase.js +++ b/src/levels/rebase/selectiveRebase.js @@ -12,25 +12,33 @@ exports.level = { "fr_FR": "Branche spaghetti", "de_DE": "Branch-Spaghetti", "es_AR": "Enslada de branches", + "es_ES": "Ensalada de ramas", "pt_BR": "Espaguete de ramos", + "gl" : "Espaguete de ramas", "ja": "ブランチスパゲッティ", "zh_CN": "纠缠不清的分支", "zh_TW": "branch 漿糊", "ru_RU": "Спутанные ветки", - "uk" : "Макарони з гілок" + "uk" : "Макарони з гілок", + "vi" : "Nhánh rối như canh hẹ", + "sl_SI": "Špageti iz Branchev" }, "hint": { "en_US": "Make sure to do everything in the proper order! Branch one first, then two, then three", "fr_FR": "Faites attention à tout faire dans le bon ordre ! La branche one d'abord, puis la seconde, puis la troisième", "de_DE": "Stelle sicher, dass du alles in der richtigen Reihenfolge machst! Branche erst one, dann two, dann three.", "es_AR": "¡Asegurate de hacer las cosas en el orden correcto! Brancheá `one` primero, después `two`, y después `three`.", + "es_ES": "¡Asegúrate de hacer las cosas en el orden correcto! Crea primero la rama `one`, después `two`, y después `three`.", "pt_BR": "Certifique-se de fazer tudo na ordem correta! Crie o ramo `one` primeiro, depois `two`, depois `three`.", + "gl" : "¡Afiánzate de facer as cousas no orde correcto! Crea ramas `one` de primeiras, e logo `two` e `three`.", "ja": "全て正しい順番で処理すること!oneが最初で、次がtwo、最後にthreeを片付ける。", "ko": "이 문제를 해결하는 방법은 여러가지가 있습니다! 체리픽(cherry-pick)이 가장 쉽지만 오래걸리는 방법이고, 리베이스(rebase -i)가 빠른 방법입니다", "zh_CN": "确保你是按照正确的顺序来操作!先操作分支 `one`, 然后 `two`, 最后才是 `three`", "zh_TW": "確認你是按照正確的順序來操作!先操作 branch `one`, 然後 `two`, 最後才是 `three`", "ru_RU": "Убедись, что у нас всё по порядку! Сначала ветка `one`, потом `two` и только потом `three`", - "uk": "Переконайся, що все йде за порядком! Спершу гілка `one`, потім `two`, і тільки потім `three`" + "uk": "Переконайся, що все йде за порядком! Спершу гілка `one`, потім `two`, і тільки потім `three`", + "vi": "Hãy chắc chắn rằng bạn làm đúng thứ tự! Nhánh `one` trước, rồi `two`, rồi mới đến `three`", + "sl_SI": "Glej da boš vse opravil v pravilnem vrstnem redu! Najprej branch ena, nato pa dva in tri." }, "startDialog": { "en_US": { @@ -43,7 +51,7 @@ exports.level = { "", "WOAHHHhhh Nelly! We have quite the goal to reach in this level.", "", - "Here we have `master` that is a few commits ahead of branches `one` `two` and `three`. For whatever reason, we need to update these three other branches with modified versions of the last few commits on master.", + "Here we have `main` that is a few commits ahead of branches `one` `two` and `three`. For whatever reason, we need to update these three other branches with modified versions of the last few commits on main.", "", "Branch `one` needs a re-ordering and a deletion of `C5`. `two` needs pure reordering, and `three` only needs one commit!", "", @@ -63,11 +71,11 @@ exports.level = { "", "WOAHHHhhh ! Nous avons pas mal d'objectifs dans ce niveau.", "", - "Actuellement nous avons `master` qui se situe quelques commits devant les branches `one` `two` et `three`. Pour une raison quelconque, nous avons besoin de mettre ces trois branches à jour avec les modifications des derniers commits sur master.", + "Actuellement nous avons `main` qui se situe quelques commits devant les branches `one` `two` et `three`. Pour une raison quelconque, nous avons besoin de mettre ces trois branches à jour avec les modifications des derniers commits sur main.", "", - "La branche `one` a besoin d'une réorganisation et de la suppression de `C5`. `two` doit simplement être reordonnée, et `three` ne nécessite qu'un commit !", + "La branche `one` a besoin d'une réorganisation et de la suppression de `C5`. `two` doit simplement être réordonnée, et `three` ne nécessite qu'un commit !", "", - "Nous vous laissons imaginer la solution pour ce niveau ; comparez avec notre solution après-coup avec la commande `show solution`. " + "Nous vous laissons imaginer la solution pour ce niveau; comparez avec notre solution après-coup avec la commande `show solution`. " ] } } @@ -83,7 +91,7 @@ exports.level = { "", "¡WOAHHHhhh Nelly! Tenemos un _pequeño_ objetivo al que llegar en este nivel.", "", - "Tenemos un `master` que está algunos commits adelante de `one`, `two` y `three`. Por alguna razón, necesitamos actualizar esas tres ramas con versiones modificadas de los últimos commits de master.", + "Tenemos un `main` que está algunos commits adelante de `one`, `two` y `three`. Por alguna razón, necesitamos actualizar esas tres ramas con versiones modificadas de los últimos commits de main.", "", "La rama `one` necesita reordenarse, y eliminar `C5`. `two` necesita sólo reordenamiento, y `three` ¡sólo necesita un commit!", "", @@ -93,6 +101,26 @@ exports.level = { } ] }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Ensalada de ramas", + "", + "¡Vaya, vaya! Tenemos un _pequeño_ objetivo al que llegar en este nivel.", + "", + "La rama `main` se encuentra algunos commits por delante de `one`, `two` y `three`. Por alguna razón, necesitamos actualizar esas tres ramas con versiones modificadas de los últimos commits de main.", + "", + "La rama `one` necesita reordenarse, y eliminar `C5`. `two` necesita sólo reordenamiento, y `three` ¡sólo necesita un commit!", + "", + "Vamos a dejar que intentes resolver este -- asegúrate de mirar la solución, después, usando `show solution`. " + ] + } + } + ] + }, "pt_BR": { "childViews": [ { @@ -103,7 +131,7 @@ exports.level = { "", "Uhuuuuu Nelly! Temos um belo de um objetivo para alcançar neste nível.", "", - "Temos aqui um `master` que está alguns commits atrás dos ramos `one`, `two` e `three`. Seja lá por qual razão, precisamos atualizar esses três outros ramos com versões modificadas dos últimos commits do master.", + "Temos aqui um `main` que está alguns commits atrás dos ramos `one`, `two` e `three`. Seja lá por qual razão, precisamos atualizar esses três outros ramos com versões modificadas dos últimos commits do main.", "", "O ramo `one` precisa de uma reordenação e da exclusão do `C5`. O `two` precisa apenas de reordenação. O `three` precisa de um único commit!", "", @@ -113,6 +141,26 @@ exports.level = { } ] }, + "gl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Espaguete de ramas", + "", + "¡Íscalle lura! Temos un _pequeno_ obxectivo que acadar neste nivel.", + "", + "Temos aquí un `main` que está algúns commits por detrás das ramas `one`, `two` e `three`. Por algunha razón, precisamos atualizar esas tres ramas con versións modificadas dos últimos commits de main.", + "", + "A rama `one` precisa de unha reordenación, e votar fora a `C5`. O `two` precisa apenas de reordenacións. O `three` precisa dun único commit!", + "", + "Ímoste deixar resolver o problema por ti mesmo -- pero non deixes de ver a nosa solución, para eso escrebe `show solution`. " + ] + } + } + ] + }, "de_DE": { "childViews": [ { @@ -123,7 +171,7 @@ exports.level = { "", "Puh! Wir haben ein ganz schön schweres Ziel für dieses Level.", "", - "Wir haben hier einen `master`, der ein paar Commits weiter ist als die Branche `one`, `two` und `three`. Aus welchem Grund auch immer müssen wir diese drei anderen Branches mit modifizierten Versionen der paar letzten Commits von `master` aktualisieren.", + "Wir haben hier einen `main`, der ein paar Commits weiter ist als die Branche `one`, `two` und `three`. Aus welchem Grund auch immer müssen wir diese drei anderen Branches mit modifizierten Versionen der paar letzten Commits von `main` aktualisieren.", "", "Branch `one` benötigt eine Umsortierung und `C5` muss gelöscht werden. `two` muss nur umsortiert werden und `three` braucht nur einen Commit!", "", @@ -143,7 +191,7 @@ exports.level = { "", "なんということでしょう。今回のレベルクリアのために、やることがたくさんあります。", "", - "いま`master`が指しているコミットの数個前のコミットに、ブランチ`one`、`two`それから`three`があります。何か事情があって、これらの3つのブランチをmasterが指している最新の状態に更新したいケースを考えます。", + "いま`main`が指しているコミットの数個前のコミットに、ブランチ`one`、`two`それから`three`があります。何か事情があって、これらの3つのブランチをmasterが指している最新の状態に更新したいケースを考えます。", "", "ブランチ`one`に対しては、順序の変更と`C5`の削除が必要です。`two`では順序の変更のみ、`three`に対しては1回だけコミットすればOKです。", "", @@ -163,7 +211,7 @@ exports.level = { "", "哇塞大神!这关我们要来点不同的!", "", - "现在我们的 `master` 分支是比 `one`、`two` 和 `three` 要多几个提交。出于某种原因,我们需要把 `master` 分支上最近的几次提交做不同的调整后,分别添加到各个的分支上。", + "现在我们的 `main` 分支是比 `one`、`two` 和 `three` 要多几个提交。出于某种原因,我们需要把 `main` 分支上最近的几次提交做不同的调整后,分别添加到各个的分支上。", "", "`one` 需要重新排序并删除 `C5`,`two` 仅需要重排排序,而 `three` 只需要提交一次。", "", @@ -183,7 +231,7 @@ exports.level = { "", "哇塞大神!這關我們要來點不同的!", "", - "現在我們的 `master` branch 是比 `one` `two` 和 `three` 這三個 branch 多了幾個 commit。由於某種原因,我們需要將 master 所新增的幾個 commit 套用到其它三個 branch 上面。", + "現在我們的 `main` branch 是比 `one` `two` 和 `three` 這三個 branch 多了幾個 commit。由於某種原因,我們需要將 main 所新增的幾個 commit 套用到其它三個 branch 上面。", "", "`one` branch 需要重新排序和取消 `C5` 這一個 commit, `two` 需要完全重排,而 `three` 只需要再一個 commit。", "", @@ -203,7 +251,7 @@ exports.level = { "", "음, 이번에는 만만치 않습니다!", "", - "여기 `master` 브랜치의 몇 번 이전 커밋에 `one`, `two`,`three` 총 3개의 브랜치가 있습니다. 어떤 이유인지는 몰라도, master의 최근 커밋 몇 개를 나머지 세 개의 브랜치에 반영하려고 합니다.", + "여기 `main` 브랜치의 몇 번 이전 커밋에 `one`, `two`,`three` 총 3개의 브랜치가 있습니다. 어떤 이유인지는 몰라도, main의 최근 커밋 몇 개를 나머지 세 개의 브랜치에 반영하려고 합니다.", "", "`one` 브랜치는 순서를 바꾸고 `C5`커밋을 삭제하고, `two`브랜치는 순서만 바꾸며, `three`브랜치는 하나의 커밋만 가져옵시다!", "", @@ -223,7 +271,7 @@ exports.level = { "", "УОУ! В этом уровне придётся попотеть!", "", - "У нас тут по несколько коммитов в ветках `one`, `two` и `three`. Не важно почему, но нам надо видоизменить эти три ветки при помощи более поздних коммитов из ветки `master`.", + "У нас тут по несколько коммитов в ветках `one`, `two` и `three`. Не важно почему, но нам надо видоизменить эти три ветки при помощи более поздних коммитов из ветки `main`.", "", "Ветка `one` нуждается в изменении порядка и удалении `C5`. `two` требует полного перемешивания, а `three` хочет получить только один коммит", "", @@ -243,7 +291,7 @@ exports.level = { "", "Ооо Неля! Ну й завданнячко.", "", - "Ми маємо гілку `master`, яка на кілька комітів попереду гілок `one`, `two` та `three`. З незрозумілих причин, нам потрібно оновити ці гілки більш пізніми змінами з мастеру.", + "Ми маємо гілку `main`, яка на кілька комітів попереду гілок `one`, `two` та `three`. З незрозумілих причин, нам потрібно оновити ці гілки більш пізніми змінами з мастеру.", "", "Гілку `one` потрібно впорядкувати і видалити `C5`. Гілку `two` також потрібно впорядкувати, а в гілку `three` потрібно додати ще один коміт!", "", @@ -252,6 +300,45 @@ exports.level = { } } ] - } + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Nhánh rối như canh hẹ", + "", + "Chààà, anh bạn! Thử thách lần này hơi khoai đây.", + "", + "Hiện tại thì nhánh `main` đang có nhiều commit hơn các nhánh `one`, `two` và `three`. Vì một lý do nào đó, ta cần cập nhật những commit trên nhánh `main` lên các nhánh còn lại kèm với một vài điều chỉnh .", + "", + "Nhánh `one` thì cần sắp xếp lại và xóa commit `C5`, trong khi đó nhánh `two` thì đơn giản sắp xếp, còn `three` thì chỉ cần một commit!", + "", + "Cố gắng động não tìm ra cách đi nhé -- khi bạn làm xong thì nhớ so sánh với đáp án của chúng tôi bằng lệnh `show solution`. " + ] + } + } + ] + },"sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Špageti iz Branchev", + "", + "WOAHHHhhh Miško! Ta stopnja bo pa pravi izziv.", + "", + "Tu imamo `main`, ki je nekaj commitov pred branchi `one`, `two` in `three`. Iz neznanega razloga moramo posodobiti te tri druge branche z modificiranimi različicami zadnjih nekaj commitov na masterju.", + "", + "Branch `one` potrebuje prerazporeditev in izbris `C5`. `two` rabi samo prerazporeditev, `three` pa potrebuje samo en commit!", + "", + "Prepustili ti bomo, da sam ugotoviš, kako tole rešiti -- vseeno lahko na koncu preveriš našo rešitev s `show solution`. " + ] + } + } + ] + }, } }; diff --git a/src/levels/remote/clone.js b/src/levels/remote/clone.js index 63ff1be4..ec30395b 100644 --- a/src/levels/remote/clone.js +++ b/src/levels/remote/clone.js @@ -7,12 +7,16 @@ exports.level = { "de_DE": "Clone Einführung", "ja" : "Clone入門", "es_AR": "Introducción a clone", + "es_ES": "Introducción a clone", "pt_BR": "Introdução à clonagem", + "gl" : "Introducción a clone", "zh_CN": "Git Clone", "zh_TW": "介紹 clone", "ru_RU": "Введение в клонирование", "ko" : "Clone 소개", - "uk" : "Знайомство з clone" + "uk" : "Знайомство з clone", + "vi" : "Giới thiệu về clone", + "sl_SI": "Uvod v Git Clone" }, "hint": { "en_US": "Just git clone!", @@ -21,11 +25,15 @@ exports.level = { "ja" : "単にgit clone!", "zh_CN": "只要 git clone 就可以了!", "es_AR": "Simplemente hacé git clone!", + "es_ES": "¡Simplemente escribe `git clone`!", "pt_BR": "Basta fazer um git clone!", + "gl" : "¡Chega con facer git clone!", "zh_TW": "只要 git clone 就好了", "ru_RU": "Простой git clone!", "ko" : "그냥 git clone 하세요!", - "uk" : "Просто git clone!" + "uk" : "Просто git clone!", + "vi" : "Đơn giản là `git clone`!", + "sl_SI": "Preprosto samo git clone!" }, "startDialog": { "en_US": { @@ -44,7 +52,7 @@ exports.level = { "", "- More importantly, remotes make coding social! Now that a copy of your project is hosted elsewhere, your friends can contribute to your project (or pull in your latest changes) very easily.", "", - "It's become very popular to use websites that visualize activity around remote repos (like [Github](https://github.com/) or [Phabricator](http://phabricator.org/)), but remote repositories _always_ serve as the underlying backbone for these tools. So it's important to understand them!" + "It's become very popular to use websites that visualize activity around remote repos (like [GitHub](https://github.com/) or [Phabricator](http://phabricator.org/)), but remote repositories _always_ serve as the underlying backbone for these tools. So it's important to understand them!" ] } }, @@ -54,7 +62,7 @@ exports.level = { "markdowns": [ "## Our Command to create remotes", "", - "Up until this point, Learn Git Branching has focused on teaching the basics of _local_ repository work (branching, merging, rebasing, etc). However now that we want to learn about remote repository work, we need a command to set up the environment for those lessons. `git clone` will be that command", + "Up until this point, Learn Git Branching has focused on teaching the basics of _local_ repository work (branching, merging, rebasing, etc). However now that we want to learn about remote repository work, we need a command to set up the environment for those lessons. `git clone` will be that command.", "", "Technically, `git clone` in the real world is the command you'll use to create _local_ copies of remote repositories (from github for example). We use this command a bit differently in Learn Git Branching though -- `git clone` actually makes a remote repository out of your local one. Sure it's technically the opposite meaning of the real command, but it helps build the connection between cloning and remote repository work, so let's just run with it for now.", "" @@ -101,7 +109,7 @@ exports.level = { "", "- Plus important encore, les dépôts distants sociabilisent le projet ! Maintenant qu'il est hébergé quelque part ailleurs, vos amis peuvent y contribuer facilement (ou récupérer vos derniers changements).", "", - "Il est devenu courant de visualiser l'activité sur dépôt distant via des sites internet (comme [Github](https://github.com/) ou [Phabricator](http://phabricator.org/)), mais les dépôts distants servent _toujours_ de colonne vertébrale à ce système. C'est donc important de les comprendre !" + "Il est devenu courant de visualiser l'activité sur dépôt distant via des sites internet (comme [GitHub](https://github.com/) ou [Phabricator](http://phabricator.org/)), mais les dépôts distants servent _toujours_ de colonne vertébrale à ce système. C'est donc important de les comprendre !" ] } }, @@ -158,7 +166,7 @@ exports.level = { "", "- Más importante, ¡los remotos sociabilizan la programación! Ahora que hay una copia de tu proyecto hosteada en otro lugar, tus amigos pueden contribuir a tu proyecto (o bajarse los últimos cambios) de un modo muy sencillo.", "", - "Se volvió bastante popular el uso de sitios web que muestran la actividad de los repositorios (como [Github](https://github.com/) or [Phabricator](http://phabricator.org/)), pero esos repositorios remotos _siempre_ sirven como el la base subyacente de esas herramientas. Así que ¡es importante entenderlos!" + "Se volvió bastante popular el uso de sitios web que muestran la actividad de los repositorios (como [GitHub](https://github.com/) o [Phabricator](http://phabricator.org/)), pero esos repositorios remotos _siempre_ sirven como la base subyacente de esas herramientas. Así que ¡es importante entenderlos!" ] } }, @@ -168,7 +176,7 @@ exports.level = { "markdowns": [ "## Nuestro comando para crear remotos", "", - "Hasta este punto, Learn Git Branching se centró en eseñar las bases del trabajo _local_ con repositorios (branchear, mergear, rebasear, etc). Sin embargo, ahora que queremos aprender sobre el trabajo con repositorios remotos, necesitamos un comando para inicializar nuestro entorno para esas lecciones. Ese comando será `git clone`", + "Hasta este punto, Learn Git Branching se centró en enseñar las bases del trabajo _local_ con repositorios (branchear, mergear, rebasear, etc). Sin embargo, ahora que queremos aprender sobre el trabajo con repositorios remotos, necesitamos un comando para inicializar nuestro entorno para esas lecciones. Ese comando será `git clone`", "", "Técnicamente, `git clone` en el mundo real es el comando que usarías para crear copias _locales_ de un repositorio remoto (uno de GitHub, por ejemplo). Acá usamos este comando de un modo un tanto distinto, en cambio -- `git clone` va a crear un repositorio remoto a partir del tuyo local. Estamos de acuerdo en que es el significado técnicamente opuesto al del comando real, pero ayuda bastante a entender la conexión entre el clonado y el trabajo en un repositorio remoto, así que vamos a vivir con ello por ahora.", "" @@ -199,6 +207,63 @@ exports.level = { } ] }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Remotes", + "", + "Los repositorios remotos no son _tan_ complicados. En el mundo actual de la computación en la nube es bastante facil pensar que hay un montón de magia detrás de los remotes de git, pero en realidad sólo son copias de tu repositorio en otra computadora. Típicamente vas a hablar con esta otra computadora a través de Internet, lo que permite transferir commits de un lado a otro.", + "", + "Habiendo dicho eso, los repositorios remotos tienen un par de propiedades interesantes:", + "", + "- Primero y principal, los remotos ¡son un backup genial! Los repositorios locales de git tienen la habilidad de restaurar archivos a un estado previo (como ya sabes), pero toda esa información se encuentra almacenada localmente. Al tener copias de tu repositorio git en otras computadoras, puedes perder todos tus datos locales y aún así retomar el trabajo en el punto donde lo habías dejado.", + "", + "- Más importante, ¡los remotos sociabilizan la programación! Ahora que hay una copia de tu proyecto hosteada en otro lugar, tus amigos pueden contribuir a tu proyecto (o bajarse los últimos cambios) de un modo muy sencillo.", + "", + "Se volvió bastante popular el uso de sitios web que muestran la actividad de los repositorios (como [GitHub](https://github.com/) or [Phabricator](http://phabricator.org/)), pero esos repositorios remotos _siempre_ sirven como la base subyacente de esas herramientas. Así que ¡es importante entenderlos!" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Nuestro comando para crear remotos", + "", + "Hasta este punto, Learn Git Branching se centró en enseñar las bases del trabajo _local_ con repositorios (crear ramas, mergear, rebasear, etc). Sin embargo, ahora que queremos aprender sobre el trabajo con repositorios remotos, necesitamos un comando para inicializar nuestro entorno para esas lecciones. Ese comando será `git clone`", + "", + "Técnicamente, `git clone` en el mundo real es el comando que usarías para crear copias _locales_ de un repositorio remoto (uno de GitHub, por ejemplo). Aquí usamos este comando de un modo un tanto distinto, en cambio -- `git clone` va a crear un repositorio remoto a partir del tuyo local. Estamos de acuerdo en que es el significado técnicamente opuesto al del comando real, pero ayuda bastante a entender la conexión entre el clonado y el trabajo en un repositorio remoto, así que vamos a vivir con ello por ahora.", + "" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Comencemos despacio y simplemente veamos cómo se ve un repositorio remoto en nuestra visualización.", + "" + ], + "afterMarkdowns": [ + "¡Ahí está! Ahora tenemos un repositorio remoto de nuestro proyecto. Parece bastante similar, salvando algunos cambios visuales para hacer evidente la distinción -- en niveles posteriores vas a ver cómo compartir trabajo entre estos repositorios." + ], + "command": "git clone", + "beforeCommand": "" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para completar este nivel, simplemente ejecuta `git clone` en tu repositorio existente. El verdadero aprendizaje viene en las próximas lecciones." + ] + } + } + ] + }, "pt_BR": { "childViews": [ { @@ -215,7 +280,7 @@ exports.level = { "", "- Ainda mais importante, repositórios remotos tornam o desenvolvimento uma atividade social! Agora que uma cópia do seu projeto está hospedada em outro lugar, seus amigos podem contribuir para o seu projeto (ou obter as suas últimas alterações) de uma forma bastante simples.", "", - "Está se tornando bastante popular o uso de websites para visualizar a atividade em repositórios (como o [Github](https://github.com/) ou o [Phabricator](http://phabricator.org/)), mas o recurso de repositórios remotos _sempre_ serve como mecanismo base para essas ferramentas. Então é importante entender como ele funciona!" + "Está se tornando bastante popular o uso de websites para visualizar a atividade em repositórios (como o [GitHub](https://github.com/) ou o [Phabricator](http://phabricator.org/)), mas o recurso de repositórios remotos _sempre_ serve como mecanismo base para essas ferramentas. Então é importante entender como ele funciona!" ] } }, @@ -256,6 +321,63 @@ exports.level = { } ] }, + "gl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Repositorios remotos en Git", + "", + "Os repositorios remotos non son complicados en git. Actualmente ca computación na nube, pódese pensar que hai moita maxia tras os repositorios remotos de git, pero para nada é así -- en verdade son copias do repositorio, pero noutra máquina. Ti podes comunicarte xeralmente con esa outra máquina por medio de internet, o que permite que mandes commits de un repositorio cara o outro.", + "", + "Dito isto, os repositorios remotos teñen propiedades interesantes:", + "", + "- Primeiro e antes de todo, os repositorios remotos serven como unha copia de seguranza! Os repositorios locais posúen a habilidade de restaurar un arquivo nun estado anterior (como xa sabes), pero toda á información está gardada. Tendo copias do repositorio noutras máquinas, incluso poderías perder tódolos datos da túa computadora, e comenzar a traballar no punto onde o deixaches no último commit.", + "", + "- Máis importante aún, ¡os repositorios remotos fan que o desenvolvemento sexa social! Agora que existe unha copia do teu código noutro lugar, os teus amigos poden contribuír no teu proxecto (ou obter os últimos cambios) dunha forma moi simple.", + "", + "Hai webs moi populares onde se pode ver a actividade dos repositorios (como [GitHub](https://github.com/) ou [Phabricator](http://phabricator.org/)), pero estes recursos remotos _sempre_ axudan como mecanismo de base para esas ferramentas. ¡Entón é importante saber cómo funcionan!" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## O noso comando para crear remotos", + "", + "Ata este punto, Learn Git Branching enfocouse en ensinar o básico respecto do traballo en repositorios _locais_ (branch, merge, rebase, etc). Entretanto, agora que queremos aprender como os repositorios remotos funcionan, precisamos dun comando para configurar o entorno para esas leccións. Este comando será `git clone`.", + "", + "Técnicamente, `git clone` no mundo real é un comando que fai copias _locais_ de repositório remotos (de GitHub para a túa máquina, por exemplo). Todavía, por motivos loxísticos, nós usaremos ese comando dunha forma un pouco diferente, Learn Git Branching -- aquí `git clone` creará un repositorio remoto a partir do repositorio local. Certamente, ese comportamento é exactamente o oposto do comando real, pero a pesares de iso axudarate a formar unha conexión mental entre a clonación e como funcionan os repositorios remotos, entón imos usalo desa forma.", + "" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Imos comenzar a modo, e só ollar cómo un repositorio remoto semellase á nosa visualización.", + "" + ], + "afterMarkdowns": [ + "¡Aquí o tes! Agora temos un respositorio remoto do noso proxecto. El é moi parecido exceto por algúns cambios visuais para ter a unha distinción visible -- nas tarefas a seguir veremos como compartir o traballo entre eses repositorios." + ], + "command": "git clone", + "beforeCommand": "" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para completar este nivel, escribe o comando `git clone`. Aprenderás algo de verdade sóamente nas próximas leccións." + ] + } + } + ] + }, "zh_TW": { "childViews": [ { @@ -272,7 +394,7 @@ exports.level = { "", "- 更重要的是, remote 讓大家一起來 coding!現在你的 project 放在 remote 上面,你的朋友可以很容易地對你的 project 做出貢獻(或者是 pull 你最後的修改) 。", "", - "使用網站去對 remote repository 做視覺化非常流行(例如 [Github](https://github.com/) 或者是 [Phabricator](http://phabricator.org/)),但這背後最大的功臣是 remote repository,因此我們務必要了解它。" + "使用網站去對 remote repository 做視覺化非常流行(例如 [GitHub](https://github.com/) 或者是 [Phabricator](http://phabricator.org/)),但這背後最大的功臣是 remote repository,因此我們務必要了解它。" ] } }, @@ -329,7 +451,7 @@ exports.level = { "", "- 还有就是, 远程让代码社交化了! 既然你的项目被托管到别的地方了, 你的朋友可以更容易地为你的项目做贡献(或者拉取最新的变更)", "", - "现在用网站来对远程仓库进行可视化操作变得越发流行了(像 [Github](https://github.com/) 或 [Phabricator](http://phabricator.org/)), 但远程仓库**永远**是这些工具的顶梁柱, 因此理解其概念非常的重要!" + "现在用网站来对远程仓库进行可视化操作变得越发流行了(像 [GitHub](https://github.com/) 或 [Phabricator](http://phabricator.org/)), 但远程仓库**永远**是这些工具的顶梁柱, 因此理解其概念非常的重要!" ] } }, @@ -381,11 +503,11 @@ exports.level = { "", "Nichts desto weniger haben entfernte Repositorys eine Menge toller Eigenschaften:", "", - "- Vor allem: sie sind ein super Backup! Lokale Git-Repositorys können deine Arbeitskopie ein jeden beliebigen früheren Zustand versetzen (wie du ja weißt), aber all diese Informationen liegen eben bei dir lokal. Wenn es Kopien von deinem Repository auf anderen Rechnern gibt, kannst du ruhig all deine Daten verlieren und trotzdem genau da weitermachen, wo du aufgehört hast.", + "- Vor allem: sie sind ein super Backup! Lokale Git-Repositorys können deine Arbeitskopie in jeden beliebigen früheren Zustand versetzen (wie du ja weißt), aber all diese Informationen liegen eben bei dir lokal. Wenn es Kopien von deinem Repository auf anderen Rechnern gibt, kannst du ruhig all deine Daten verlieren und trotzdem genau da weitermachen, wo du aufgehört hast.", "", - "- Noch wichtiger: Remotes geben dem Entwickeln eine soziale Komponente! Wenn eine Kopie deines Projekts woanders liegt können deine Freunde sehr einfach etwas zu dem Projekt beitragen (oder sich deine neuesten Änderungen holen).", + "- Noch wichtiger: Remotes geben dem Entwickeln eine soziale Komponente! Wenn eine Kopie deines Projekts woanders liegt, können deine Freunde sehr einfach etwas zu dem Projekt beitragen (oder sich deine neuesten Änderungen holen).", "", - "Websites, die die Aktivitäten um diese entfernten Repositorys darstellen (wie [Github](https://github.com/) oder [Phabricator](http://phabricator.org/)) erfreuen sich zunehmender Beliebtheit, aber entfernte Repositorys sind _immer_ das Rückgrat für diese Werkzeuge. Deshalb ist es wichtig, sie zu verstehen." + "Websites, die die Aktivitäten um diese entfernten Repositorys darstellen (wie [GitHub](https://github.com/) oder [Phabricator](http://phabricator.org/)) erfreuen sich zunehmender Beliebtheit, aber entfernte Repositorys sind _immer_ das Rückgrat für diese Werkzeuge. Deshalb ist es wichtig, sie zu verstehen." ] } }, @@ -397,7 +519,7 @@ exports.level = { "", "Bis jetzt hat sich Learn Git Branching darauf konzentriert, die Grundlagen der _lokalen_ Arbeit mit Repositorys zu vermitteln (Branche anlegen, zusammenführen, Rebasen etc). Jetzt wollen wir allerdings lernen mit entfernten Repositorys zu arbeiten und brauchen für die Level eine entsprechende Umgebung. Die schaffen wir mit `git clone`.", "", - "In der Realität ist `git clone` eigentlich der Befehl, mit dem du eine _lokale_ Kopie eines _entfernten_ Repositorys erstellst (das zum Beispiel auf Github liegt). Wir benutzen diesen Befehl in Learn Git Branching allerdings ein wenig anders -- hier macht `git clone` tatsächlich eine Kopie von deinem lokalen Repository auf einem \"entfernten Server\". Klar, das ist eigentlich genau das Gegenteil von dem was der echte Befehl macht, aber es hilft den Zusammenhang zwischen Cloning und der Arbeit mit entfernten Repositorys herzustellen, also machen wir's einfach so.", + "In der Realität ist `git clone` eigentlich der Befehl, mit dem du eine _lokale_ Kopie eines _entfernten_ Repositorys erstellst (das zum Beispiel auf GitHub liegt). Wir benutzen diesen Befehl in Learn Git Branching allerdings ein wenig anders -- hier macht `git clone` stattdessen eine Kopie von deinem lokalen Repository auf einem \"entfernten Server\". Klar, das ist eigentlich genau das Gegenteil von dem, was der echte Befehl macht, aber es hilft den Zusammenhang zwischen Cloning und der Arbeit mit entfernten Repositorys herzustellen, also machen wir's einfach so.", "" ] } @@ -442,7 +564,7 @@ exports.level = { "", "- それよりも大切なこととして、リモートではコードをより一般的に公開できます!プロジェクトのコピーが別の場所に保存されているため、友達などが簡単にそのプロジェクトに参加したり最近の変更をpullしたりできます。", "", - "最近ではリモートリポジトリに関するデータをビジュアル的に表示するウェブサイト([Github](https://github.com/)や[Phabricator](http://phabricator.org/)など)の使用が人気を集めていますが、リモートリポジトリは_そのいずれの_ウェブサイトの裏にも使われています。なので理解する必要があります。" + "最近ではリモートリポジトリに関するデータをビジュアル的に表示するウェブサイト([GitHub](https://github.com/)や[Phabricator](http://phabricator.org/)など)の使用が人気を集めていますが、リモートリポジトリは_そのいずれの_ウェブサイトの裏にも使われています。なので理解する必要があります。" ] } }, @@ -548,15 +670,15 @@ exports.level = { "markdowns": [ "## Git Remote(원격)", "", - "원격 저장소라는것이 사실 그다지 복잡한 개념은 아닙니다. 오늘날의 클라우드 컴퓨팅을 떠올리면 git remote의 이면에 수많은 마법이 부려지고 있을것 같지만, 사실 git remote 또 하나의 컴퓨터에 있는 여러분의 저장소의 복사본일 뿐입니다. 여러분은 일반적으로 인터넷을 통해서 이 또 하나의 컴퓨터와 커밋을 주고 받는등 대화를 할 수 있습니다.", + "원격 저장소라는 것이 사실 그다지 복잡한 개념은 아닙니다. 오늘날의 클라우드 컴퓨팅을 떠올리면 git remote의 이면에 수많은 마법이 부려지고 있을 것 같지만, 사실 git remote 또 하나의 컴퓨터에 있는 여러분의 저장소의 복사본일 뿐입니다. 여러분은 일반적으로 인터넷을 통해서 이 또 하나의 컴퓨터와 커밋을 주고받는 등의 대화를 할 수 있습니다.", "", - "소개한김에 자랑까지 하자면 원격 저장소는 수많은 장점들이 있습니다:", + "소개한 김에 자랑까지 하자면 원격 저장소는 수많은 장점이 있습니다:", "", - "- 무엇보다 먼저, 원격 저장소는 백업으로서의 역할을 훌륭하게 수행합니다! 로컬 git 저장소는 파일들을 이전의 상태로 되돌리는 기능을 가지고 있습니다(아시다시피). 하지만 그 모든 정보가 로컬(내PC)에 저장되어 있습니다. 여러분의 git 저장소를 다른 컴퓨터에 복사본을 가지고있으면 로컬 데이터를 다 잃더라도 다른 컴퓨터에 남아있는 복사본으로 다시 출발 할 수 있습니다.", + "- 무엇보다 먼저, 원격 저장소는 백업으로서의 역할을 훌륭하게 수행합니다! 로컬 git 저장소는 파일들을 이전의 상태로 되돌리는 기능을 가지고 있습니다(아시다시피). 하지만 그 모든 정보가 로컬(내 PC)에 저장되어 있습니다. 여러분의 git 저장소를 다른 컴퓨터가 복사본으로 가지고 있으면 로컬 데이터를 다 잃더라도 다른 컴퓨터에 남아있는 복사본으로 다시 출발 할 수 있습니다.", "", - "- 더 중요한 것은, 원격 저장소를 통해 코딩을 다른 사람들과 함께 할 수 있다는것입니다. 여러분의 프로젝트의 복사본이 어느곳에선가 호스트되기때문에 여러분의 친구가 프로젝트에 아주 쉽게 기여할 수 있게됩니다(최근의 변화를 pull하거나).", + "- 더 중요한 것은, 원격 저장소를 통해 코딩을 다른 사람들과 함께 할 수 있다는 것입니다. 여러분의 프로젝트의 복사본이 어느 곳에선가 호스트되기 때문에 여러분의 친구가 프로젝트에 아주 쉽게 기여할 수 있게 됩니다(최근의 변화를 pull하거나).", "", - "원격 저장소에서의 활동을 시각화해주는 웹 사이트들을 사용하는것이 추세입니다 ([Github](https://github.com/) 또는 [Phabricator](http://phabricator.org/)등이 있습니다). 원격 저장소가 _항상_ 이러한 도구들의 중심 뼈대를 이루고있습니다. 그래서 잘 아는것이 중요해요!" + "원격 저장소에서의 활동을 시각화해주는 웹 사이트들을 사용하는 것이 추세입니다. ([GitHub](https://github.com/) 또는 [Phabricator](http://phabricator.org/)등이 있습니다). 원격 저장소가 _항상_ 이러한 도구들의 중심 뼈대를 이루고 있습니다. 그래서 잘 아는 것이 중요해요!" ] } }, @@ -566,9 +688,9 @@ exports.level = { "markdowns": [ "## 원격 저장소를 생성하는 명령어", "", - "지금까지, Git 브랜치 배우기는 _로컬_ 저장소가 어떻게 활용되는지에 대해 중점적으로 소개해 왔습니다(브랜치, 합병, 리베이스 등등). 이제 원격 저장소를 어떻게 활용하는지에 대해 배워보려고 합니다. 앞으로 이어질 레슨의 환경을 마련할 명령어가 필요합니다. `git clone`가 바로 그 명령어 입니다.", + "지금까지, Git 브랜치 배우기는 _로컬_ 저장소가 어떻게 활용되는지에 대해 중점적으로 소개해 왔습니다(브랜치, 합병, 리베이스 등등). 이제 원격 저장소를 어떻게 활용하는지에 대해 배워보려고 합니다. 앞으로 이어질 레슨의 환경을 마련할 명령어가 필요합니다. `git clone`이 바로 그 명령어입니다.", "", - "실제로 `git clone`은 원격 저장소의 복사본을 _로컬_에 생성할때 사용하는 명령어 입니다(github에서 가져올때 라던가). Git 브랜치 배우기에서는 이 명령어를 살짝 다르게 사용합니다 -- `git clone`이 당신의 로컬 저장소에서 원격 저장소를 생성해냅니다. 물론 실제 명령어와 반대로 작동하는 것이지만 클론과 원격 저장소 사이의 연결관계를 이해하는데 도움이되서 이렇게 했습니다. 일단은 그냥 해봅시다.", + "실제로 `git clone`은 원격 저장소의 복사본을 _로컬_에 생성할때 사용하는 명령어입니다(github에서 가져올 때라던가). Git 브랜치 배우기에서는 이 명령어를 살짝 다르게 사용합니다 -- `git clone`이 당신의 로컬 저장소에서 원격 저장소를 생성해냅니다. 물론 실제 명령어와 반대로 작동하는 것이지만 클론과 원격 저장소 사이의 연결관계를 이해하는데 도움이되서 이렇게 했습니다. 일단은 그냥 해봅시다.", "" ] } @@ -613,7 +735,7 @@ exports.level = { "", "- Що не менш важливо, віддалені репозиторії роблять програмування соціальним! Коли копія твого проекту розміщена в мережі, твої друзі мають змогу допомогти твоєму проекту (чи стягнути останні зміни) без зайвих зусиль.", "", - "Стало дуже популярним користуватися веб-сайтами, що візуалізують активність на віддалених репозиторіях (наприклад [Github](https://github.com/) чи [Phabricator](http://phabricator.org/)), але віддалені репозиторії _завжди_ слугують як основа цих сервісів. Тому важливо розуміти їх!" + "Стало дуже популярним користуватися веб-сайтами, що візуалізують активність на віддалених репозиторіях (наприклад [GitHub](https://github.com/) чи [Phabricator](http://phabricator.org/)), але віддалені репозиторії _завжди_ слугують як основа цих сервісів. Тому важливо розуміти їх!" ] } }, @@ -653,6 +775,120 @@ exports.level = { } } ] + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Remotes(Kho lưu trữ từ xa)", + "", + "Thực ra thì kho remote cũng không khó hiểu lắm đâu. Giờ đây đâu đâu cũng thấy điện toán đám mây nên ai ai cũng tưởng git remote nó là cái gì đó ma thuật lắm, nhưng chúng thực ra chỉ là những bản sao chép ko chứa của bạn lên máy tính khác. Bạn có thể giao tiếp với chúng qua internet, tù đó mà chuyển giao commit qua lại.", + "", + "Vì lẽ đó mà kho remote có những đặc tính tuyệt vời:", + "", + "- Trước hết, có tác dụng như là bản sao dự phòng! Bạn đã biết rằng kho địa phương có thể khôi phục trở lại trạng thái trước đó, nhưng tất cả thông tin đó chỉ được lưu trữ cục bộ. Bằng cách sao chép toàn bộ kho chứa của bạn lên máy tính ở xa, bạn hoàn toàn có thể mất hết dữ liệu tại máy tính mà vẫn tiếp tục làm việc như chưa có gì xảy ra.", + "", + "- Quạn trọng hơn nữa, kho remote khiến lập trình có tính cộng đồng hơn! Bây giờ bản sao dự án của bạn đã được lưu trũ ở nơi khác, bạn bè của bạn có thể đóng góp (hoặc kéo về cập nhật mới nhất) dự án của bạn rất dễ dàng.", + "", + "Trực quan hóa các kho lưu trữ từ xa bằng cách sử dụng các trang web đang trở nên phổ biến hơn (như [GitHub] (https://github.com/) hoặc [Photypeator] (http://phovenator.org/)), nhưng các kho lưu trữ từ xa * * Luôn luôn ** là trụ cột của các công cụ này, vì vậy điều quan trọng là phải hiểu khái niệm này!" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Câu lệnh của chúng tôi để tạo kho lưu trữ từ xa", + "", + "Cho đến bây giờ, Learn Git Branching đã tập trung dạy về làm việc trên kho chứa _địa phương_ (rẽ nhánh `branch`, hợp nhánh `merge`, dịch chuyển nhánh `rebase`, vân vân ...). Nhưng bây giờ ta lại muốn học về làm việc trên kho lưu trữ từ xa, ta cần một câu lệnh để cài đặt môi trường cho những bài học này. Đó là `git clone`", + "", + "Về mặt kỹ thuật, thì `git clone` thực tế là câu lệnh dùng để tạo một bản sao chép _địa phương_ của khó chứa từ xa (ví dụ từ github chẳng hạn). Nhưng trong Learn Git Branching ta sẽ dùng câu lệnh này hơi khác biệt một chút -- `git clone` sẽ tạo ra một bản sao chép lên kho lưu trữu từ xa dựa trên kho chứa cục bộ của bạn. Điều này hoàn toàn ngược lại với câu lệnh thực tế, nhưng nó giúp ta nhân bản và làm việc với kho lưu trữ từ xa, nên ta sẽ dùng nó trong quá trình học.", + "" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Nào cùng khởi động bằng cách nhìn xem kho lưu trữ từ xa trông như thế nào (trong mô tả của chúng tôi).", + "" + ], + "afterMarkdowns": [ + "Nó đây rồi! Giờ ta đã có kho lưu trữ dự án chúng ta từ xa. Nhìn nó cũng khá tương tự chỉ là được minh họa khác biệt một chút -- đến các cấp độ sau ta sẽ tìm hiểu thêm về cách thức trao đổi nội dung giữa các kho chứa này." + ], + "command": "git clone", + "beforeCommand": "" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Để hoàn thành cấp độ này chỉ cần đơn giản gõ lệnh `git clone` để sao chép kho chứa hiện tại. Ta sẽ học sâu hơn ở các bài học sau." + ] + } + } + ] + }, + "sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Oddaljeni Git", + "", + "Oddaljeno repozitoriji sploh niso tako zakomplicirani. V današnjem svetu oblačnih storitev si lahko kdo predstavlja, da je veliko čarovnije za oddaljnim Gitom, a gre preprosto za tvoj repozitorij na drugem računalniku. Ponavadi lahko komuniciraš s tem računalnikom preko interneta, ki ti omogoča da prenašaš commite naprej in nazaj.", + "", + "Poleg tega imajo oddaljeni repozitoriji tudi veliko super lastnosti:", + "", + "- Prvič, oddaljenost služi za odlično rezervo! Lokalni git repozitoriji imajo možnost obnovitve datotek v prejšnje stanje (kot že veš), ampak vse te informacije so shranjene lokalno. S tem da imaš shranjene kopije gita na drugih računalnikih, lahko izgubiš vse tvoje lokalne podatke, pa imaš še zmeraj opcijo nadaljevati, kjer si ostal.", + "", + "- Še pomembneje, kodiranje lahko naredijo družabno! Sedaj, ko je kopija tvojega projekta nekje objavljena, lahko tvoji prijatelji pomagajo tvojemu projektu (ali pridobijo zadnje spremembe) zelo enostavno.", + "", + "Uporaba strani, ki vizualizirajo oddaljene repozitorije je postala zelo popularna (npr. [GitHub](https://github.com/) ali [Phabricator](http://phabricator.org/)), ampak bistvo teh strani vseeno predstavljajo oddaljeni repozitoriji. Zato je pomembno, da jih razumemo!" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Naši ukazi za kreiranje oddaljenih repozitorijev", + "", + "Do te točke, se je Learn Git Branching osredotočil na učenje osnov dela na lokalnih repozitorijih (branching, merging, rebasing, itd). Ampak sedaj, ko se hočemo naučiti še o delu na oddaljenih repozitorijih, potrebujemo ukaz, da postavi okolje za te lekcije. `git clone` bo ta ukaz.", + "", + "Tehnično je `git clone` v pravem svetu ukaz, ki ga boš uporabil za ustvarjanje lokalnih kopij oddaljenih repozitorijev (iz githuba naprimer). Mi uporabljamo ta ukaz nekoliko drugače na Learn Git Branching -- `git clone` ubistvu naredi oddaljen repozitorij iz tvojega lokalnega. Seveda, tehnično je nasproten pomen pravega ukaza, ampak pomaga ustvariti povezavo med kloniranjem in delom na oddaljenem repozitoriju, zato ga zdaj pač uporabljajmo.", + "" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Začnimo počasi in poglejmo kako izgleda oddaljen repozitorij (v naši vizualizaciji).", + "" + ], + "afterMarkdowns": [ + "Evo ga! Sedaj imamo oddaljen repozitorij našega projekta. Izgleda precej podoben razen nekaj vizualnih sprememb, da se opazi razlika -- v kasnejših stopnjah boš spoznal, kako si delimo delo preko teh repozitorijev." + ], + "command": "git clone", + "beforeCommand": "" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Za dokončanje te stopnje, uporabi `git clone` na svojem obstoječem repozitoriju. Pravo učenje pride v lekcijah, ki sledijo." + ] + } + } + ] } } }; diff --git a/src/levels/remote/fakeTeamwork.js b/src/levels/remote/fakeTeamwork.js index 22d2b866..7046d744 100644 --- a/src/levels/remote/fakeTeamwork.js +++ b/src/levels/remote/fakeTeamwork.js @@ -8,12 +8,16 @@ exports.level = { "de_DE": "Teamarbeit simulieren", "ja" : "擬似的なチーム作業", "es_AR": "Simulando el trabajo en equipo", + "es_ES": "Simulando el trabajo en equipo", "pt_BR": "Simulando trabalho em equipe", + "gl" : "Simulando o traballo no repositorio", "zh_CN": "模拟团队合作", "zh_TW": "模擬團隊合作", "ru_RU": "Коллективная работа", "uk" : "Симуляція колективної роботи", - "ko" : "가짜 팀워크" + "ko" : "가짜 팀워크", + "vi" : "Giả lập làm việc nhóm", + "sl_SI": "Lažno Ekipno Delo" }, "hint": { "en_US": "remember you can specify the number of commits to fake", @@ -21,12 +25,16 @@ exports.level = { "de_DE": "Nicht vergessen, du kannst angeben wieviele Commits simuliert werden sollen.", "ja" : "擬似的に作成するコミット数を指定できるのをお忘れなく", "es_AR": "Acordate que podés especificar cuántos commits simular", + "es_ES": "Recuerda que puedes especificar cuántos commits simular", "pt_BR": "Lembre-se que você pode especificar quantos commits quer simular", + "gl" : "Lembra que podes especifar cantos commits queres simular", "zh_CN": "记住你可以指定仿真提交的个数", "zh_TW": "你要記得指定要送多少個 commit 出去", "ru_RU": "помните, Вы можете указать количество фейковых коммитов", "uk" : "пам’ятай що ти можеш вказати кількість фейкових комітів", - "ko" : "가장할 커밋의 갯수를 조절할 수 있습니다." + "ko" : "가장할 커밋의 갯수를 조절할 수 있습니다.", + "vi" : "Nhớ rằng bạn có thể chỉ định số lượng commit để giả lập.", + "sl_SI": "Spomni se, da lahko določiš število lažnih commitov." }, "startDialog": { "en_US": { @@ -49,7 +57,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "The default behavior of `fakeTeamwork` is to simply plop down a commit on master" + "The default behavior of `fakeTeamwork` is to simply plop down a commit on main." ], "afterMarkdowns": [ "There we go -- the remote was updated with a new commit, and we haven't downloaded that commit yet because we haven't run `git fetch`." @@ -62,10 +70,10 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "You can also specify the number of commits or the branch by appending them to the command" + "You can also specify the number of commits or the branch by appending them to the command." ], "afterMarkdowns": [ - "With one command we simulated a teammate pushing three commits to the `foo` branch on our remote" + "With one command we simulated a teammate pushing three commits to the `foo` branch on our remote." ], "command": "git fakeTeamwork foo 3", "beforeCommand": "git branch foo; git clone" @@ -103,7 +111,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Le comportement par défaut de `fakeTeamwork` est tout simplement de faire apparaître un commit sur le master distant :" + "Le comportement par défaut de `fakeTeamwork` est tout simplement de faire apparaître un commit sur le main distant :" ], "afterMarkdowns": [ "Voilà : le dépôt distant a été mis à jour avec un nouveau commit, et nous n'avons pas encore téléchargé ce commit parce que nous n'avons pas exécuté la commande `git fetch`." @@ -119,7 +127,7 @@ exports.level = { "Vous pouvez aussi spécifier le nombre de commits ou la branche en les ajoutant à la fin de la commande." ], "afterMarkdowns": [ - "Avec une seule commande, nous avons simulé un collègue ayant pushé 3 commits sur la branche `foo` de notre dépôt distant" + "Avec une seule commande, nous avons simulé un collègue ayant pushé 3 commits sur la branche `foo` de notre dépôt distant." ], "command": "git fakeTeamwork foo 3", "beforeCommand": "git branch foo; git clone" @@ -147,7 +155,7 @@ exports.level = { "", "Entonces, hay algo medio tramposo acá -- para algunas de las lecciones siguientes, necesitamos explicarte cómo bajar cambios introducidos en el repositorio remoto.", "", - "Eso significa que escencialmente tenemos que \"hacer de cuenta\" que el repositorio remoto fue actualizado por alguún colega, amigo o colaborador tuyo, incluso a veces en alguna rama específica o una cantidad determinada de commits.", + "Eso significa que esencialmente tenemos que \"hacer de cuenta\" que el repositorio remoto fue actualizado por algún colega, amigo o colaborador tuyo, incluso a veces en alguna rama específica o una cantidad determinada de commits.", "", "Para lograr esto, introdujimos el bien llamado comando ¡`git fakeTeamwork`! Es bastante auto-explicativo: simula trabajo de nuestros colegas. Veamos una demo..." ] @@ -157,7 +165,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "El comportamiento por default de `fakeTeamwork` es simplemente crear un commit en master" + "El comportamiento por default de `fakeTeamwork` es simplemente crear un commit en main." ], "afterMarkdowns": [ "Ahí está: el remoto se actualizó con un nuevo commit, y todavía no nos bajamos ese commit porque aún no hicimos `git fetch`." @@ -170,10 +178,10 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "También podés especificar la cantidad de commits o la ramma agregándolos al comando" + "También podés especificar la cantidad de commits o la ramma agregándolos al comando." ], "afterMarkdowns": [ - "Con un único comando simulamos que un compañero de equipo pusheó tres commits a la rama `foo` de nuestro remoto" + "Con un único comando simulamos que un compañero de equipo pusheó tres commits a la rama `foo` de nuestro remoto." ], "command": "git fakeTeamwork foo 3", "beforeCommand": "git branch foo; git clone" @@ -191,6 +199,60 @@ exports.level = { } ] }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Simulando la colaboración", + "", + "Entonces, hay algo un poco tramposo -- para algunas de las lecciones siguientes, necesitamos explicarte cómo descargar cambios introducidos en el repositorio remoto.", + "", + "Eso significa que escencialmente tenemos que \"tener en cuenta\" que el repositorio remoto fue actualizado por algún colega, amigo o colaborador tuyo, incluso a veces en alguna rama específica o una cantidad determinada de commits.", + "", + "Para lograr esto, introdujimos el bien llamado comando ¡`git fakeTeamwork`! Es bastante autoexplicativo: simula trabajo de nuestros colegas. Veamos una demo..." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "El comportamiento por default de `fakeTeamwork` es simplemente crear un commit en main." + ], + "afterMarkdowns": [ + "Ahí está: el remoto se actualizó con un nuevo commit, y todavía no nos bajamos ese commit porque aún no hicimos `git fetch`." + ], + "command": "git fakeTeamwork", + "beforeCommand": "git clone" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "También puedes especificar la cantidad de commits o la ramma agregándolos al comando." + ], + "afterMarkdowns": [ + "Con un único comando simulamos que un compañero de equipo pusheó tres commits a la rama `foo` de nuestro remoto." + ], + "command": "git fakeTeamwork foo 3", + "beforeCommand": "git branch foo; git clone" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Los niveles siguientes van a ser algo difíciles, así que vamos a exigirte un poco más en este nivel.", + "", + "Anímate y crea un remoto (con `git clone`), simula algunos cambios en ese remoto, haz commit en tu repo local, y luego haz pull de esos cambios. ¡Es como si fueran varias lecciones en una!" + ] + } + } + ] + }, "pt_BR": { "childViews": [ { @@ -211,7 +273,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "O comportamento padrão do `fakeTeamwork` é simplesmente fazer aparecer um commit no master" + "O comportamento padrão do `fakeTeamwork` é simplesmente fazer aparecer um commit no main." ], "afterMarkdowns": [ "Aqui vamos nos -- o repositório remoto foi atualizado com um novo commit, e ainda não baixamos esse commit porque não executamos um `git fetch`." @@ -224,10 +286,10 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Você também pode especificar o número de commits ou o ramo, anexando-os ao comando" + "Você também pode especificar o número de commits ou o ramo, anexando-os ao comando." ], "afterMarkdowns": [ - "Com um único comando, nós simulamos um colega enviando 3 commits para o ramo `foo` do repositório remoto" + "Com um único comando, nós simulamos um colega enviando 3 commits para o ramo `foo` do repositório remoto." ], "command": "git fakeTeamwork foo 3", "beforeCommand": "git branch foo; git clone" @@ -245,6 +307,60 @@ exports.level = { } ] }, + "gl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Simulando o traballo no repositorio", + "", + "Entón, hai algo con trampa aquí -- para algunhas das leccións seguintes, precisamos explicarche cómo baixar os cambios introducidos no repositorio remoto.", + "", + "Eso significa que escencialmente temos que \"finxir\" que o repositorio remoto foi actualizado por algún compañeiro, amigo ou incluso nalgunha rama específica a cantidade de commits feitos.", + "", + "Para acadar esto, introduxemos o ben chamado comando `git fakeTeamwork`! É bastante auto-explicativo: semella traballo dos nosos colegas. Vexamos una demo..." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "O comportamento por defecto de `fakeTeamwork` é simplemente crear un commit en main na rama remota." + ], + "afterMarkdowns": [ + "Ahí o tes: a rama remota actualizouse cun novo commit, e aínda non nos baixamos ese commit porque inda non fixemos `git fetch`." + ], + "command": "git fakeTeamwork", + "beforeCommand": "git clone" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Tamén podes especificar a cantidad de commits ou a rama agregándoos ó comando." + ], + "afterMarkdowns": [ + "Cun único comando simulamos que un colega do equipo empurrou tres commits á rama `foo` do noso remoto." + ], + "command": "git fakeTeamwork foo 3", + "beforeCommand": "git branch foo; git clone" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Os niveis seguintes van ser un pouco máis complicados, así que imos a esixirte un pouco máis neste nivel.", + "", + "Anímate e crea unha rama remota (con `git clone`), e simula algúns cambios no repositorio remoto, logo desto, fai commit do teu repo local, e logo descarga os cambios. ¡É coma varias leccións nunha soa!" + ] + } + } + ] + }, "zh_TW": { "childViews": [ { @@ -265,7 +381,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "`fakeTeamwork` 的預設行為是在送一個 commit 給 master 分支" + "`fakeTeamwork` 的預設行為是在送一個 commit 給 main 分支" ], "afterMarkdowns": [ "我就說吧!remote 已經藉由一個新的 commit 而更新了,而且因為我們還沒有用 `git fetch`,所以表示我們還沒有下載該 commit。" @@ -319,7 +435,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "`fakeTeamwork` 默认操作就是在远程仓库的 master 分支上做一次提交。" + "`fakeTeamwork` 默认操作就是在远程仓库的 main 分支上做一次提交。" ], "afterMarkdowns": [ "完成了 —— 远程仓库增加了一个新提交,我们还没有下载它,因为我们还没有执行 `git fetch`。" @@ -363,7 +479,7 @@ exports.level = { "", "Hier ist das Problem -- für einige der folgenden Level müssen wir lernen, wie man Änderungen vom entfernten Server holt.", "", - "Das heißt wir müssen im Grunde \"so tun\" also ob der Server von einem Kollegen / Freund / Mitarbeiter aktualisiert worden wäre, manchmal ein bestimmter Branch oder eine bestimmte Anzahl von Commits.", + "Das heißt wir müssen im Grunde \"so tun\", als ob der Server von einem Kollegen / Freund / Mitarbeiter aktualisiert worden wäre, manchmal ein bestimmter Branch oder eine bestimmte Anzahl von Commits.", "", "Um das zu tun führen wir den passend benannten Befehl `git fakeTeamwork` ein! Er ist ziemlich selbsterklärend, schauen wir uns ihn an ..." ] @@ -373,10 +489,10 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Das normale Verhalten von `fakeTeamwork` ist es, einen Commit auf den entfernten `master` zu machen." + "Das normale Verhalten von `fakeTeamwork` ist es, einen Commit auf den entfernten `main` zu machen." ], "afterMarkdowns": [ - "Da haben wir's -- der Server ist mit einem neuen Commit aktualisiert worden und wir haben ihn noch nicht lokal, weil wir nicht `git fetch` oder `git pull` ausgeführt haben." + "Da haben wir's -- der Server ist mit einem neuen Commit aktualisiert worden und wir haben ihn noch nicht lokal, weil wir weder `git fetch` noch `git pull` ausgeführt haben." ], "command": "git fakeTeamwork", "beforeCommand": "git clone" @@ -427,7 +543,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Поведение команды `fakeTeamwork` по умолчанию заключается в том, чтобы просто \"инициировать\" коммит на master-е" + "Поведение команды `fakeTeamwork` по умолчанию заключается в том, чтобы просто \"инициировать\" коммит на main-е" ], "afterMarkdowns": [ "Ну вот - удалённый репозиторий был изменён при помощи добавления нового коммита, и мы ещё не скачали этот коммит, потому что не запустили команду `git fetch`." @@ -537,7 +653,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "За замовчуванням `fakeTeamwork` просто додасть коміт в гілку `master`" + "За замовчуванням `fakeTeamwork` просто додасть коміт в гілку `main`." ], "afterMarkdowns": [ "Є -- до віддаленого репозиторію додався ще один коміт, проте ми ще його не звантажили, оскільки ще не виконали `git fetch`." @@ -624,6 +740,114 @@ exports.level = { } } ] + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Mô phỏng hợp tác", + "", + "Bây giờ khó đây -- để chuẩn bị cho những bài học tới, chúng tôi cần chỉ bạn cách kéo về những cập nhật có trên kho chứa từ xa.", + "", + "Có nghĩa là ta cần \"giả vờ\" kho chứa từ xa được cập nhật bởi đồng nghiệp / bạn / cộng tác viên của bạn, có khi là một nhánh xác định hoặc là một số commit.", + "", + "Để làm điều này, chúng tôi sẽ giới thiệu cho bạn một lệnh tự tạo `git fakeTeamwork`! Cái tên nói lên tất cả, cùng xem thử bản giới thiệu..." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Hành xử mặc định của `fakeTeamwork` đơn giản là tạo ra một commit ở trên nhánh main từ xa." + ], + "afterMarkdowns": [ + "Đó -- kho chứa từ xa đã được cập nhật thêm một commit, và ta chưa tải commit đó xuống vì ta chưa hề chạy lệnh `git fetch`." + ], + "command": "git fakeTeamwork", + "beforeCommand": "git clone" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Bạn cũng có thể chỉ định số lượng commit bằng cách thêm con số đằng sau câu lệnh." + ], + "afterMarkdowns": [ + "Chỉ với một câu lệnh ta có thể giả lập tạo ra 3 commit trên nhánh `foo` từ xa của ta." + ], + "command": "git fakeTeamwork foo 3", + "beforeCommand": "git branch foo; git clone" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Các cấp độ tới sẽ khá là khó, nên ở cấp độ này chúng tôi sẽ yêu cầu bạn thêm một chút.", + "", + "Sao chép một kho chứa từ xa (sử dụng `git clone`), sau đó mô phỏng một số thay đổi trong kho chứa từ xa mà bạn vừa tạo, sau đó thực hiện một số commit trên nhánh cục bộ của riêng bạn, sau đó kéo các thay đổi từ kho chứa từ xa. Nhiều bài học trong một bài." + ] + } + } + ] + }, + "sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Simulacija sodelovanja", + "", + "Tule imamo izziv -- za nekaj naslednjih lekcij te moramo naučiti, kako potegniti dol spremembe, ki so bile narejene na oddaljenem repozitoriju.", + "", + "To pomeni, da se moramo pravzaprav \"pretvarjati\", da je oddaljen branch posodobil kak sodelavec, včasih na določenem branchu ali določeno število commitov.", + "", + "Da bi to lahko naredili, smo uvedli ukaz `git fakeTeamwork`! Poglejmo prikaz ..." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Privzeto delovanje `fakeTeamwork` je, da samo doda commit na main:" + ], + "afterMarkdowns": [ + "Tako -- oddaljen repo je bil posodobljen z novim commitom, katerega še nismo potegnili k sebi, ker še nismo pognali ukaza `git fetch`." + ], + "command": "git fakeTeamwork", + "beforeCommand": "git clone" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Prav tako lahko določimo tudi število commitov ali ime brancha tako, da jih dodamo na koncu:" + ], + "afterMarkdowns": [ + "Z enim ukazom smo simulirali sodelavca, ki je dodal tri commite na `foo` branch na našem oddaljnem repotu." + ], + "command": "git fakeTeamwork foo 3", + "beforeCommand": "git branch foo; git clone" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Naslednje stopnje bodo precej težke, zato od tebe v tej stopnji zahtevamo še več.", + "", + "Naredi oddaljen repo (z `git clone`), simuliraj nekaj sprememb na tem repotu, sam commitaj, nato pa potegni dol spremembe. Kot da bi bilo več lekcij v eni!" + ] + } + } + ] } } }; diff --git a/src/levels/remote/fetch.js b/src/levels/remote/fetch.js index 5501167b..eb1dd903 100644 --- a/src/levels/remote/fetch.js +++ b/src/levels/remote/fetch.js @@ -8,12 +8,16 @@ exports.level = { "de_DE": "Git Fetch", "ja" : "Git Fetch", "es_AR": "git fetch", + "es_ES": "git fetch", "pt_BR": "Git Fetch", + "gl" : "Git Fetch", "zh_CN": "Git Fetch", "zh_TW": "git fetch", "ru_RU": "Git fetch", "uk" : "Git fetch", - "ko" : "Git Fetch" + "ko" : "Git Fetch", + "vi" : "Git Fetch", + "sl_SI": "Git Fetch" }, "hint": { "en_US": "just run git fetch!", @@ -21,12 +25,16 @@ exports.level = { "de_DE": "Einfach git fetch ausführen!", "ja" : "単にgit fetchを実行!", "es_AR": "Simplemente ¡hacé git fetch!", + "es_ES": "Simplemente ¡escribe git fetch!", "pt_BR": "Simplesmente chame git fetch!", + "gl" : "¡Sinxelamente fai git fetch!", "zh_CN": "只需要运行 git fetch 命令!", "zh_TW": "只要下 git fetch 指令", "ru_RU": "Просто выполните git fetch!", "uk" : "Просто виконай git fetch!", - "ko" : "그냥 git fetch를 하세요!" + "ko" : "그냥 git fetch를 하세요!", + "vi" : "Gõ git fetch là được!", + "sl_SI": "Le izvedi git fetch!" }, "startDialog": { "en_US": { @@ -41,7 +49,7 @@ exports.level = { "", "In this lesson we will learn how to fetch data _from_ a remote repository -- the command for this is conveniently named `git fetch`.", "", - "You'll notice that as we update our representation of the remote repository, our _remote_ branches will update to reflect that new representation. This ties into the previous lesson on remote branches" + "You'll notice that as we update our representation of the remote repository, our _remote_ branches will update to reflect that new representation. This ties into the previous lesson on remote branches." ] } }, @@ -52,7 +60,7 @@ exports.level = { "Before getting into the details of `git fetch`, let's see it in action! Here we have a remote repository that contains two commits that our local repository does not have." ], "afterMarkdowns": [ - "There we go! Commits `C2` and `C3` were downloaded to our local repository, and our remote branch `o/master` was updated to reflect this." + "There we go! Commits `C2` and `C3` were downloaded to our local repository, and our remote branch `o/main` was updated to reflect this." ], "command": "git fetch", "beforeCommand": "git clone; git fakeTeamwork 2" @@ -67,7 +75,7 @@ exports.level = { "`git fetch` performs two main steps, and two main steps only. It:", "", "* downloads the commits that the remote has but are missing from our local repository, and...", - "* updates where our remote branches point (for instance, `o/master`)", + "* updates where our remote branches point (for instance, `o/main`)", "", "`git fetch` essentially brings our _local_ representation of the remote repository into synchronization with what the _actual_ remote repository looks like (right now).", "", @@ -84,7 +92,7 @@ exports.level = { "markdowns": [ "### What fetch doesn't do", "", - "`git fetch`, however, does not change anything about _your_ local state. It will not update your `master` branch or change anything about how your file system looks right now.", + "`git fetch`, however, does not change anything about _your_ local state. It will not update your `main` branch or change anything about how your file system looks right now.", "", "This is important to understand because a lot of developers think that running `git fetch` will make their local work reflect the state of the remote. It may download all the necessary data to do that, but it does _not_ actually change any of your local files. We will learn commands in later lessons to do just that :D", "", @@ -125,7 +133,7 @@ exports.level = { "Avant d'aller dans les détails de `git fetch`, voyons-le en action ! Ici nous avons un dépôt distant qui contient deux commits que notre dépôt local n'a pas." ], "afterMarkdowns": [ - "Voilà ! Les commits `C2` et `C3` ont été téléchargés dans notre dépôt local, et notre branche distante `o/master` a été mise à jour pour refléter cela." + "Voilà ! Les commits `C2` et `C3` ont été téléchargés dans notre dépôt local, et notre branche distante `o/main` a été mise à jour pour refléter cela." ], "command": "git fetch", "beforeCommand": "git clone; git fakeTeamwork 2" @@ -140,7 +148,7 @@ exports.level = { "`git fetch` procède en deux étapes principales, ni plus ni moins. Cela :", "", "* télécharge les commits que le dépôt distant possède mais qui ne sont pas dans le nôtre, puis...", - "* met à jour nos branches distantes (par exemple, `o/master`).", + "* met à jour nos branches distantes (par exemple, `o/main`).", "", "`git fetch` prend en fait notre représentation _locale_ du dépôt distant pour la synchroniser avec ce à quoi le dépôt distant ressemble _réellement_ (à ce moment-là).", "", @@ -157,7 +165,7 @@ exports.level = { "markdowns": [ "### Ce que fetch ne fait pas", "", - "`git fetch`, cependant, ne change rien à _votre_ état local. Il ne met pas à jour votre branche `master` et ne va pas changer quelque chose aux fichiers qui se trouvent actuellement dans votre répertoire de travail.", + "`git fetch`, cependant, ne change rien à _votre_ état local. Il ne met pas à jour votre branche `main` et ne va pas changer quelque chose aux fichiers qui se trouvent actuellement dans votre répertoire de travail.", "", "C'est important à comprendre car un nombre important de développeurs pensent qu'exécuter `git fetch` va mettre leur dépôt local dans le même état que le distant. Cela peut télécharger toutes les données nécessaires pour faire cela, mais cela ne change en réalité _rien_ sur vos fichiers locaux. Les prochains niveaux seront justement dédiés aux commandes qui permettent de faire cela :D", "", @@ -187,7 +195,7 @@ exports.level = { "", "En esta lección aprenderemos cómo traer (hacer `fetch`) datos _desde_ un repositorio remoto - el comando para esto se llama, convenientemente, `git fetch`).", "", - "Vas a notar que a medida que actualicemos nuestra representación de nuestro repositorio remoto, nuestras ramas _remotas_ van a actualizarse para reflejar esa nueva representación. Esto está ligado a la lección anterior sobre ramas remotas" + "Vas a notar que a medida que actualicemos nuestra representación de nuestro repositorio remoto, nuestras ramas _remotas_ van a actualizarse para reflejar esa nueva representación. Esto está ligado a la lección anterior sobre ramas remotas." ] } }, @@ -198,7 +206,7 @@ exports.level = { "Antes de entrar en los detalles de `git fetch`, veámoslo en acción. Acá tenemos un repositorio remoto que contiene dos commits que nuestro repositorio local no tiene." ], "afterMarkdowns": [ - "¡Ahí vamos! Bajamos los commits `C2` y `C3` a nuestro repositorio local, y nuestra rama remota `o/master` fue actualizada para reflejar este cambio." + "¡Ahí vamos! Bajamos los commits `C2` y `C3` a nuestro repositorio local, y nuestra rama remota `o/main` fue actualizada para reflejar este cambio." ], "command": "git fetch", "beforeCommand": "git clone; git fakeTeamwork 2" @@ -213,9 +221,9 @@ exports.level = { "`git fetch` hace dos simples pasos, y sólo dos simples pasos:", "", "* baja los commits que el remoto tiene pero no están en nuestro repositorio local, y...", - "* actualiza a dónde apuntan nuestras ramas remotas (por ejemplo, `o/master`)", + "* actualiza a dónde apuntan nuestras ramas remotas (por ejemplo, `o/main`)", "", - "`git fetch` escencialmente sincroniza nuestra representación _local_ del repositorio remoto con el _verdadero_ estado del repositorio remoto (en este momento).", + "`git fetch` esencialmente sincroniza nuestra representación _local_ del repositorio remoto con el _verdadero_ estado del repositorio remoto (en este momento).", "", "Si recordás la lección anterior, dijimos que las ramas remotas reflejan el estado de los repositorios remotos _desde_ la última vez que hablaste con ellos. ¡`git fetch` es la manera en que hablás con esos remotos! Espero que ahora esté clara la conexión entre las ramas remotas y `git fetch`.", "", @@ -230,7 +238,7 @@ exports.level = { "markdowns": [ "### ¿Qué *no* hace fetch?", "", - "Sin embargo, `git fetch` no modifica en absoluto _tu_ estado local. No va a actualizar tu rama `master` ni va a cambiar nada sobre cómo se ve tu sistema de archivos en este momento.", + "Sin embargo, `git fetch` no modifica en absoluto _tu_ estado local. No va a actualizar tu rama `main` ni va a cambiar nada sobre cómo se ve tu sistema de archivos en este momento.", "", "Es importante entender esto, porque un montón de desarrolladores piensan que correr `git fetch` hará que su estado local refleje el estado del remoto. `git fetch` puede descargar los datos necesarios para hacerlo, pero *no* cambia ninguno de tus archivos locales. Vamos a aprender otros comandos para hacer eso más adelante :D", "", @@ -242,7 +250,80 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Para completar este nivel, simplemente corré `git fetch` y bajate todos los commits" + "Para completar este nivel, simplemente corré `git fetch` y bajate todos los commits." + ] + } + } + ] + }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Fetch", + "", + "Trabajar con remotos en git en realidad se reduce a transferir datos _de_ y _hacia_ otros repositorios. Mientras podamos mandar commits de un lado al otro, podemos compartir cualquier tipo de actualización registrada por git (y, por ende, compartir trabajo, archivos nuevos, ideas nuevas, cartas de amor, etc).", + "", + "En esta lección aprenderemos cómo traer (hacer `fetch`) datos _desde_ un repositorio remoto - el comando para esto se llama, convenientemente, `git fetch`).", + "", + "Vas a notar que a medida que actualicemos nuestra representación de nuestro repositorio remoto, nuestras ramas _remotas_ van a actualizarse para reflejar esa nueva representación. Esto está ligado a la lección anterior sobre ramas remotas." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Antes de entrar en los detalles de `git fetch`, veámoslo en acción. Aquí tenemos un repositorio remoto que contiene dos commits que nuestro repositorio local no tiene." + ], + "afterMarkdowns": [ + "¡Allá vamos! Bajamos los commits `C2` y `C3` a nuestro repositorio local, y nuestra rama remota `o/main` fue actualizada para reflejar este cambio." + ], + "command": "git fetch", + "beforeCommand": "git clone; git fakeTeamwork 2" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### ¿Qué hace fetch?", + "", + "`git fetch` hace dos simples pasos, y sólo dos simples pasos:", + "", + "* baja los commits que el remoto tiene pero no están en nuestro repositorio local, y...", + "* actualiza a dónde apuntan nuestras ramas remotas (por ejemplo, `o/main`)", + "", + "`git fetch` escencialmente sincroniza nuestra representación _local_ del repositorio remoto con el _verdadero_ estado del repositorio remoto (en este momento).", + "", + "Si recuerdas la lección anterior, dijimos que las ramas remotas reflejan el estado de los repositorios remotos _desde_ la última vez que hablaste con ellos. ¡`git fetch` es la manera en la que hablas con esos remotos! Espero que ahora esté clara la conexión entre las ramas remotas y `git fetch`.", + "", + "Usualmente, `git fetch` habla con el repositorio a través de internet (usando un protocolo como `http://` o `git://`).", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### ¿Qué *no* hace fetch?", + "", + "Sin embargo, `git fetch` no modifica en absoluto _tu_ estado local. No va a actualizar tu rama `main` ni va a cambiar nada sobre cómo se ve tu sistema de archivos en este momento.", + "", + "Es importante entender esto, porque un montón de desarrolladores piensan que correr `git fetch` hará que su estado local refleje el estado del remoto. `git fetch` puede descargar los datos necesarios para hacerlo, pero *no* cambia ninguno de tus archivos locales. Vamos a aprender otros comandos para hacer eso más adelante :D", + "", + "Entonces, después de todo, puedes pensar sobre `git fetch` como un proceso de descarga." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para completar este nivel, simplemente ejecuta `git fetch` y bájate todos los commits." ] } } @@ -260,7 +341,7 @@ exports.level = { "", "Nesta lição vamos aprender como baixar dados _de_ um repositório remoto -- o comando para isso é convenientemente chamado de `git fetch`.", "", - "Você perceberá que conforme atualizarmos a representação do repositório remoto, nossos ramos _remotos_ atualizar-se-ão para refletir essa nova representação. Isso tem a ver com o que vimos na lição anterior sobre ramos remotos" + "Você perceberá que conforme atualizarmos a representação do repositório remoto, nossos ramos _remotos_ atualizar-se-ão para refletir essa nova representação. Isso tem a ver com o que vimos na lição anterior sobre ramos remotos." ] } }, @@ -271,7 +352,7 @@ exports.level = { "Antes de entrar nos detalhes do `git fetch`, vejamo-no em ação! Aqui temos um repositório remoto que contém dois commits que nosso repositório local não possui." ], "afterMarkdowns": [ - "Lá vamos nós! Os commits `C2` e `C3` foram baixados para o nosso repositório local, e nosso ramo remoto `o/master` foi atualizado para refletir esse fato." + "Lá vamos nós! Os commits `C2` e `C3` foram baixados para o nosso repositório local, e nosso ramo remoto `o/main` foi atualizado para refletir esse fato." ], "command": "git fetch", "beforeCommand": "git clone; git fakeTeamwork 2" @@ -286,7 +367,7 @@ exports.level = { "O `git fetch` realiza dois passos principais, e somente estes dois passos principais. Ele:", "", "* Baixa os commits que o repositório remoto possui mas que estão faltando no repositório local, e...", - "* Atualiza a referência para a qual os ramos remotos (por exemplo, `o/master`) estão apontando", + "* Atualiza a referência para a qual os ramos remotos (por exemplo, `o/main`) estão apontando", "", "O `git fetch` essencialmente faz com que nossa representação _local_ do repositório remoto fique sincronizada com a forma com que o repositório remoto _de fato_ se parece (naquele momento).", "", @@ -303,7 +384,7 @@ exports.level = { "markdowns": [ "### O que o fetch NÃO faz", "", - "O `git fetch`, no entanto, não muda nada do estado _local_ do repositório. Ele não atualiza o seu ramo `master` nem muda nada na forma como o seu sistema de arquivos está no momento.", + "O `git fetch`, no entanto, não muda nada do estado _local_ do repositório. Ele não atualiza o seu ramo `main` nem muda nada na forma como o seu sistema de arquivos está no momento.", "", "É importante entender isso, pois muitos desenvolvedores pensam que executar `git fetch` fará com que o trabalho local reflita o estado do repositório remoto. Ele pode até baixar todos os dados necessários para fazê-lo, mas ele _não_ muda de fato nenhum dos arquivos locais. Vamos aprender comandos para fazê-lo nas lições a seguir :D", "", @@ -321,6 +402,79 @@ exports.level = { } ] }, + "gl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Fetch", + "", + "Traballar con respositorios remotos en Git, a fin de contas, resúmese en transferir datos _dun_ repositorio _cara_ outros repositorios. Dende que podemos enviar commits dun lado cara o outro, poderemos compartir calquera tipo de actualización que sexa xerada por git (e polo tanto compartir o traballo, novos arquivos, novas ideas, cartas de amor, etc).", + "", + "Nesta lección imos aprender como baixar os cambios _dun_ repositorio remoto -- o comando para iso é `git fetch`.", + "", + "Percibirás que conforme atualizamos a representación do repositorio remoto, as nosas ramas _remotas_ actualizaranse para reflexar a nova representación. Iso ten que ver co que vimos na lección anterior sobre as ramas remotas." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Ántes de entrar nos detalles de `git fetch`, vexámolo en acción! Aquí temos un repositorio remoto que contén dous commits que o noso repositorio local non ten." + ], + "afterMarkdowns": [ + "Alá imos! Os commits `C2` e `C3` baixáronse ó noso repositorio local, e a nosa rama `o/main` actualizouse para reflexar ese cambio." + ], + "command": "git fetch", + "beforeCommand": "git clone; git fakeTeamwork 2" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### O que fai o fetch", + "", + "`git fetch` fai dous pasos pasos principais, e soamente estes dous pasos princpipais. Son:", + "", + "* Baixa os commits que o repositório remoto contén pero non temos nos no noso repositoiro local, e...", + "* Actualiza a referencia nas ramas remotas (por exemplo, `o/main`) nas que se está apuntando", + "", + "`git fetch` esencialmente fai que a nosa representación _local_ do repositorio remoto se sincronice ca forma que posúe o repositorio remoto, _de feito_ parecese (nese momento).", + "", + "Se ti lembras a lección anterior, nos dixemos que as ramas remotas reflexan o estado dos repositorios remotos _dende a última vez_ na que ti fixeches un commit dese repositorio. O `git fetch` é a única forma de falar con eses repositorios remotos! Agardo que a conexión entre as ramas remotas e o `git fetch` esté clara dabondo agora.", + "", + "`git fetch` xeralmente fala co repositorio remoto por medio da rede (usando un protocolo como `http://`, `git://` ou `ssh`).", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### O que fetch NON fai", + "", + "`git fetch`, por agora, non cambia nada no estado _local_ do repositorio. El solo actualiza a rama `main` sen facer cambios na forma de cómo está o teu sistema de arquivos nese momento.", + "", + "É importante entender iso, xa que moitos desenvolvedores pensan que executar `git fetch` fará que o traballo local se vexa modificado polo repositorio remoto. El pode que baixara todos os cambios necesarios para facelo, pero, o comando _non_ cambia cómo están os teus arquivos locais. Imos aprender comandos para facer esas conexións :D", + "", + "A fin de contas, ti podes pensar en `git fetch` como unha descarga." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para rematar este nivel, so executa `git fetch` e baixa todos os commits!" + ] + } + } + ] + }, "zh_TW": { "childViews": [ { @@ -344,7 +498,7 @@ exports.level = { "在講到 `git fetch` 的細節之前,我們要先來看一下例子!在這裡我們有一個新增了兩個 commit 的 remote repository,而且我們的 local repository 並沒有包含這兩個 commit。" ], "afterMarkdowns": [ - "看吧!commit `C2` 以及 `C3` 已經被下載到我們的 local repository,而且我們的 remote branch `o/master` 也更新了。" + "看吧!commit `C2` 以及 `C3` 已經被下載到我們的 local repository,而且我們的 remote branch `o/main` 也更新了。" ], "command": "git fetch", "beforeCommand": "git clone; git fakeTeamwork 2" @@ -359,7 +513,7 @@ exports.level = { "`git fetch` 只有執行了兩個主要步驟,包含:", "", "* 下載 remote 有的 commit,但是在我們的 local repository 是沒有該 commit。還有...", - "* 更新我們 remote branch 所指向的地方(例如, `o/master`)", + "* 更新我們 remote branch 所指向的地方(例如, `o/main`)", "", "基本上,`git fetch` 同步了我們的 local repository 以及 remote repository 的最新狀態。", "", @@ -376,7 +530,7 @@ exports.level = { "markdowns": [ "### fetch 沒有做的事情", "", - "然而,`git fetch` 並不會影響到在你的 local repository 中的 `master` branch,他並不會將你的 `master` branch 更新到最新的狀態。", + "然而,`git fetch` 並不會影響到在你的 local repository 中的 `main` branch,他並不會將你的 `main` branch 更新到最新的狀態。", "", "這個觀念很重要,因為很多程式設計師以為 `git fetch` 可以讓他們在 local repository 上面的工作跟 remote repository 的工作可以同步。它是會下載同步所需的資料,但是不會更新任何的檔案,我們會在後面的教學中提到如何做到這件事情。:D", "", @@ -406,7 +560,7 @@ exports.level = { "", "本节课我们将学习如何从远程仓库获取数据 —— 命令如其名,它就是 `git fetch`。", "", - "你会看到当我们从远程仓库获取数据时, 远程分支也会更新以反映最新的远程仓库。在上一了我们已经提及过这一点了。" + "你会看到当我们从远程仓库获取数据时, 远程分支也会更新以反映最新的远程仓库。在上一节课程中我们已经提及过这一点了。" ] } }, @@ -417,7 +571,7 @@ exports.level = { "在解释 `git fetch` 前,我们先看看实例。这里我们有一个远程仓库, 它有两个我们本地仓库中没有的提交。" ], "afterMarkdowns": [ - "就是这样了! `C2`,`C3` 被下载到了本地仓库,同时远程分支 `o/master` 也被更新,反映到了这一变化" + "就是这样了! `C2`,`C3` 被下载到了本地仓库,同时远程分支 `o/main` 也被更新,反映到了这一变化" ], "command": "git fetch", "beforeCommand": "git clone; git fakeTeamwork 2" @@ -432,7 +586,7 @@ exports.level = { "`git fetch` 完成了仅有的但是很重要的两步:", "", "* 从远程仓库下载本地仓库中缺失的提交记录", - "* 更新远程分支指针(如 `o/master`)", + "* 更新远程分支指针(如 `o/main`)", "", "`git fetch` 实际上将本地仓库中的远程分支更新成了远程仓库相应分支最新的状态。", "", @@ -449,7 +603,7 @@ exports.level = { "markdowns": [ "### git fetch 不会做的事", "", - "`git fetch` 并不会改变你本地仓库的状态。它不会更新你的 `master` 分支,也不会修改你磁盘上的文件。", + "`git fetch` 并不会改变你本地仓库的状态。它不会更新你的 `main` 分支,也不会修改你磁盘上的文件。", "", "理解这一点很重要,因为许多开发人员误以为执行了 `git fetch` 以后,他们本地仓库就与远程仓库同步了。它可能已经将进行这一操作所需的所有数据都下载了下来,但是**并没有**修改你本地的文件。我们在后面的课程中将会讲解能完成该操作的命令 :D", "", @@ -477,7 +631,7 @@ exports.level = { "", "In Git mit entfernten Repositorys zu arbeiten lässt sich wirklich auf das Hin- und Zurückübertragen von Daten reduzieren. Solange wir Commits hin und her schicken können, können wir jede Art Update teilen, das von Git getrackt wird (und somit Arbeit, neue Dateien, neue Ideen, Liebesbriefe etc. teilen).", "", - "In diesem Level werden wir lernen, wie man Daten _von_ einem entfernten Repository holt -- der entsprechende Befehl heißt praktischerweise `git fetch`.", + "In diesem Level werden wir lernen, wie man Daten _von_ einem entfernten Repository holt -- der entsprechende Befehl heißt `git fetch`.", "", "Dir wird auffallen, dass mit der Aktualisierung unserer Darstellung des entfernten Repositorys die _Remote_ Branches auf den neuesten Stand gebracht werden. Das passt zum vorherigen Level über Remote Branches." ] @@ -487,10 +641,10 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Bevor wir uns die Einzelheiten von `git fetch` ansehen wollen wir es mal in Aktion sehen. Wir haben hier ein entferntes Repository, das zwei Commits hat die in unserem lokalen Repository fehlen." + "Bevor wir uns die Einzelheiten von `git fetch` ansehen wollen wir es mal in Aktion sehen. Wir haben hier ein entferntes Repository, das zwei Commits hat, die in unserem lokalen Repository fehlen." ], "afterMarkdowns": [ - "Das war's! Die Commits `C2` und `C3` wurden zu unserem Repository heruntergeladen und unser Remote Branch `o/master` wurde aktualisiert." + "Das war's! Die Commits `C2` und `C3` wurden zu unserem Repository heruntergeladen und unser Remote Branch `o/main` wurde aktualisiert." ], "command": "git fetch", "beforeCommand": "git clone; git fakeTeamwork 2" @@ -505,9 +659,9 @@ exports.level = { "`git fetch` führt genau zwei Schritte aus:", "", "* Es lädt die Commits herunter, die im lokalen Repository fehlen, und ...", - "* aktualisiert die Remote Branches wo nötig (zum Beispiel, `o/master`).", + "* aktualisiert die Remote Branches wo nötig (zum Beispiel `o/main`).", "", - "`git fetch` synchronisiert im Prinzip unsere _lokale_ Abbildung des entfernten Repositorys mit dem wie das entfernte Repository _tatsächlich_ aussieht (in diesem Moment).", + "`git fetch` synchronisiert im Prinzip unsere _lokale_ Abbildung des entfernten Repositorys mit dem, wie das entfernte Repository _tatsächlich_ aussieht (in diesem Moment).", "", "Wie du dich vielleicht erinnerst, haben wir im letzten Level gesagt, dass die Remote Branches den Zustand der Branches auf dem entfernten Repository darstellen _seit_ du das letzte Mal dieses Repository angesprochen hast. `git fetch` ist die Methode mit der du das Repository ansprichst! Der Zusammenhang zwischen Remote Branches und `git fetch` ist damit hoffentlich klar.", "", @@ -522,9 +676,9 @@ exports.level = { "markdowns": [ "### Was Fetch nicht tut", "", - "`git fetch` ändert allerdings überhaupt nichts an _deinen_ lokalen Branches. Es aktualisiert nicht deinen `master` oder ändert irgendetwas an deinem Checkout.", + "`git fetch` ändert allerdings überhaupt nichts an _deinen_ lokalen Branches. Es aktualisiert nicht deinen `main` oder ändert irgendetwas an deinem Checkout.", "", - "Das ist wichtig zu wissen, denn eine Menge Entwickler glauben, wenn sie `git fetch` ausführen würden ihre lokalen Branches auf den Stand des entfernten Repositorys gebracht. Es lädt zwar alle Daten herunter, damit man diese Aktualisierung durchführen kann, aber es ändert _nichts_ an deinen lokalen Branches. Wir werden in späteren Level Befehle genau dafür kennenlernen. :D", + "Das ist wichtig zu wissen, denn eine Menge Entwickler glauben, wenn sie `git fetch` ausführen, würden ihre lokalen Branches auf den Stand des entfernten Repositorys gebracht. Es lädt zwar alle Daten herunter, damit man diese Aktualisierung durchführen kann, aber es ändert _nichts_ an deinen lokalen Branches. Wir werden in späteren Level Befehle genau dafür kennenlernen. :D", "", "Am Ende des Tages kannst du dir `git fetch` also als den Download-Schritt vorstellen." ] @@ -563,7 +717,7 @@ exports.level = { "`git fetch`の説明に入る前に、その動作を見てみましょう。ここに、ローカルリポジトリにない二個のコミットを含んでいるリモートブランチがあります。" ], "afterMarkdowns": [ - "やりました!`C2`、`C3`コミットがローカルリポジトリにダウンロードされ、`o/master`リモートブランチに反映されました。" + "やりました!`C2`、`C3`コミットがローカルリポジトリにダウンロードされ、`o/main`リモートブランチに反映されました。" ], "command": "git fetch", "beforeCommand": "git clone; git fakeTeamwork 2" @@ -578,7 +732,7 @@ exports.level = { "`git fetch`は、主に二つのステップだけで動作します。それは以下のようなものです:", "", "* リモートにあってローカルリポジトリにないコミットをダウンロードする", - "* リモートブランチの位置を更新する(例えば、`o/master`)", + "* リモートブランチの位置を更新する(例えば、`o/main`)", "", "`git fetch`は本質的には、_実際_のリモートリポジトリと同じように見えるような形でリモートリポジトリの_ローカル_の情報に同期します(ちょうど今のように)。", "", @@ -595,7 +749,7 @@ exports.level = { "markdowns": [ "### fetchがしてくれないもの", "", - "`git fetch`は、しかしながら、_あなたの_ローカルの状態は変更しません。あなたの`master`ブランチや他のもの、今現在のあなたのファイルシステムが見せているものを更新しないのです。", + "`git fetch`は、しかしながら、_あなたの_ローカルの状態は変更しません。あなたの`main`ブランチや他のもの、今現在のあなたのファイルシステムが見せているものを更新しないのです。", "", "これは理解する上で重要なことです。なぜなら、多くの技術者は`git fetch`がリモートの状態をローカルの作業場に反映してくれると思っているからです。必要なデータはダウンロードされるかもしれませんが、ローカルのファイルを実際に変更するというようなことは_してくれない_のです。私たちは、この後のレッスンでもこのようなコマンドを学びます :D", "", @@ -636,7 +790,7 @@ exports.level = { "Прежде чем углубляться в детали команды `git fetch`, давайте взглянем на её визуализацию в действии! Здесь у нас имеется удалённый репозиторий, который содержит в себе два коммита, отсутствующих в нашем локальном репозитории." ], "afterMarkdowns": [ - "Вот и всё! Коммиты `C2` и `C3` были успешно скачаны в наш локальный репозиторий, и наша удалённая ветка `o/master` отобразила эти изменения соответствующим образом." + "Вот и всё! Коммиты `C2` и `C3` были успешно скачаны в наш локальный репозиторий, и наша удалённая ветка `o/main` отобразила эти изменения соответствующим образом." ], "command": "git fetch", "beforeCommand": "git clone; git fakeTeamwork 2" @@ -651,7 +805,7 @@ exports.level = { "`git fetch` выполняет две и только две основные операции. А именно:", "", "* связывается с указанным удалённым репозиторием и забирает все те данные проекта, которых у вас ещё нет, при этом...", - "* у вас должны появиться ссылки на все ветки из этого удалённого репозитория (например, `o/master`)", + "* у вас должны появиться ссылки на все ветки из этого удалённого репозитория (например, `o/main`)", "", "Фактически, `git fetch` синхронизирует _локальное_ представление удалённых репозиториев с тем, что является _актуальным_ на текущий момент времени.", "", @@ -709,7 +863,7 @@ exports.level = { "Перед тим, як почати розбиратися з `git fetch`, спробуймо його в дії! Тут ми маємо віддалений репозиторій, що містить два коміти, яких немає в нашому локальному сховищі." ], "afterMarkdowns": [ - "Ось, маєш! Коміти `C2` та `C3` було завантажено до нашого локального сховища й наша віддалена гілка `o/master` була відповідно оновлена." + "Ось, маєш! Коміти `C2` та `C3` було завантажено до нашого локального сховища й наша віддалена гілка `o/main` була відповідно оновлена." ], "command": "git fetch", "beforeCommand": "git clone; git fakeTeamwork 2" @@ -724,7 +878,7 @@ exports.level = { "`git fetch` виконує дві основні дії, і тільки дві дії. Він:", "", "* звантажує коміти, які містить віддалене сховище, але яких немає в локальному сховищі, та...", - "* оновлює посилання віддаленого бранчу (наприклад, `o/master`)", + "* оновлює посилання віддаленого бранчу (наприклад, `o/main`)", "", "Якщо коротко, `git fetch` приводить репрезентацію віддаленого репозиторію в локальному сховищі до _актуального_ стану справжнього віддаленого репозиторію.", "", @@ -741,7 +895,7 @@ exports.level = { "markdowns": [ "### Чого не робить fetch", "", - "Тим не менш, `git fetch` нічого не змінює в _твоєму_ локальному стані. Він не оновить твою гілку `master` і не змінить того, як наразі виглядає локальна файлова система.", + "Тим не менш, `git fetch` нічого не змінює в _твоєму_ локальному стані. Він не оновить твою гілку `main` і не змінить того, як наразі виглядає локальна файлова система.", "", "Це важливо зрозуміти, тому що багато розробників думають, що `git fetch` оновить їхні локальні данні до стану віддаленого репозиторію. Він дійсно звантажить всі потрібні дані, щоб це зробити, але він _не змінить_ автоматично жодних локальних файлів. Ми вивчимо команди, які це роблять, в наступних уроках :D", "", @@ -782,7 +936,7 @@ exports.level = { "`git fetch`의 세부사항을 알아보기 전에 일단 눈으로 먼저 확인해 봅시다! 여기 로컬 저장소에는 없는 두개의 커밋이 있는 원격 저장소가 있습니다." ], "afterMarkdowns": [ - "됐습니다! 커밋 `C2` 와 `C3`가 우리의 로컬 저장소로 다운로드 되었고, 원격 브랜치 `o/master`가 이것을 반영하기 위해 업데이트 되었습니다." + "됐습니다! 커밋 `C2` 와 `C3`가 우리의 로컬 저장소로 다운로드 되었고, 원격 브랜치 `o/main`가 이것을 반영하기 위해 업데이트 되었습니다." ], "command": "git fetch", "beforeCommand": "git clone; git fakeTeamwork 2" @@ -797,7 +951,7 @@ exports.level = { "`git fetch`는 두가지의 중요한 단계를 수행합니다. 사실 이 두 단계만을 진행합니다. 그것은 :", "", "* 원격 저장소에는 있지만 로컬에는 없는 커밋들을 다운로드 받습니다. 그리고... ", - "* 우리의 원격 브랜치가 가리키는곳을 업데이트합니다 (예를들어, `o/master`)", + "* 우리의 원격 브랜치가 가리키는곳을 업데이트합니다 (예를들어, `o/main`)", "", "`git fetch`는 본질적으로 _로컬_에서 나타내는 원격 저장소의 상태를 _실제_ 원격 저장소의 (지금)상태와 동기화합니다.", "", @@ -814,7 +968,7 @@ exports.level = { "markdowns": [ "### fetch는 무엇을 하지 않는가", "", - "`git fetch`는 그러나, _여러분의_ 로컬 상태는 전혀 바꾸지 않는습니다. 여러분의 `master` 브랜치도 업데이트하지 않고 파일 시스템의 모습이던 그 어떤것도 바꾸지 않습니다.", + "`git fetch`는 그러나, _여러분의_ 로컬 상태는 전혀 바꾸지 않는습니다. 여러분의 `main` 브랜치도 업데이트하지 않고 파일 시스템의 모습이던 그 어떤것도 바꾸지 않습니다.", "", "이것을 이해하는게 아주 중요한데, 왜냐하면 수 많은 개발자들이 `git fetch`를 하면 자신의 로컬 작업이 변경되어 원격 저장소의 모습을 반영해 업데이트 될것이라고 생각하기 때문입니다. 앞의 과정에 필요한 데이터를 다운로드는 하지만, 실제로 로컬 파일들이나 브랜치를 변경하지는 않습니다. 이것을 하기위한 명령어들은 뒤에서 배우겠습니다 :D", "", @@ -831,6 +985,152 @@ exports.level = { } } ] + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Fetch", + "", + "Lam việc với git remote về căn bản là chuyển giao dữ liệu _qua_ và _lại_ giữa các kho chứa. Miễn là ta có thể chia sẻ qua lại các commit, ta có thể chia sẻ bất kỳ cập nhật gì được theo dõi bở git (và từ đó chia sẻ thành quả, tập tin mới, ý tưởng mới, thư tình, các kiểu con đà điểu.).", + "", + "Ở bài học này ta sẽ học cách lấy dữ liệu về _từ_ một kho chứa từ xa -- lệnh đó là `git fetch`.", + "", + "Bạn sẽ nhận thấy rằng khi ta cập nhật đại điện kho chứa từ xa, Nhánh _từ xa_ của ta cũng được cập nhật để phản ánh đại diện đó. Điều này liên quan đến bài học trước về nhánh từ xa." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Trước khi đi vào chi tiết về `git fetch`, hãy xem cách nó hoạt động! Ở đây ta có một kho chứa từ xa trong đó chứa 2 commit mà kho chứa địa phương của ta không có." + ], + "afterMarkdowns": [ + "Đó! Commit `C2` và `C3` đã được tải xuống kho chứa cục bộ của ta, và nhánh từ xa `o/main` của ta đã được cập nhật để phản ánh điều này." + ], + "command": "git fetch", + "beforeCommand": "git clone; git fakeTeamwork 2" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Fetch làm gì", + "", + "`git fetch` thực hiện 2 bước chính, và chỉ 2 bước chính. Nó:", + "", + "* tải xuống commit có trên kho chứa từ xa mà kho chứa cục bộ của ta không có, và...", + "* cập nhật nơi mà nhánh từ xa của ta trỏ tới (ví dụ nhánh `o/main`)", + "", + "Về căn bản thì `git fetch` đưa đại diện _địa phương_ của kho chứa từ xa của ta về trạng thái đồng bộ với trạng thái _thực tế_ của kho chứa từ xa (ngay lúc này).", + "", + "Nếu bạn còn nhớ thì trong bài học trước, chúng tôi có đề cập rằng nhánh từ xa phản ánh trạng thái của kho chứa từ xa _kể từ_ kể từ lần cuối bạn tương tác với các nhánh từ xa đó. `git fetch` chính là cách để tương tác với cách nhánh từ xa! Hi vọng chúng tôi đã làm sáng tỏ sự liên kết giữa nhánh từ xa và `git fetch`.", + "", + "`git fetch` thường tương tác với kho chứa từ xa bằng Internet (thông qua các giao thức như `http://` hoặc `git://`).", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### fetch không làm gì", + "", + "Tuy nhiên, `git fetch` không hề thay đổi trạng thái kho chứa _địa phương_ của bạn. Nó sẽ không cập nhật nhánh `main` hay thay đổi bất kỳ điều gì trong hệ thống tập tin hiện tại của bạn.", + "", + "Điều này rất quan trọng, vì nhiều nhà phát triển nghĩ rằng `git fetch` sẽ làm kho chứa địa phương của họ phản ánh trạng thái của kho chúa từ xa. Nó có thể tải xuống tất cả dữ liệu cần thiết, nhưng nó thực tế _không_ thay đổi bất cứ thứ gì trên tập tin địa phương của bạn. Ta sẽ học lệnh để làm điều đó sau :D", + "", + "Nói tóm lại, bạn có thể coi `git fetch` thuần túy như một bước tải xuống." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Để hoàn thành cấp độ này, đơn giản hãy gõ `git fetch` để tải xuống tất cả commit!" + ] + } + } + ] + }, + "sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Fetch", + "", + "Delanje z git oddaljnemi repoti je v bistvu le premikanje podatkov na in z drugih repozitorijev. Dokler lahko pošiljamo commite naprej in nazaj, lahko delimo bilokakšno posodobitev, kateri git sledi (in posledično delimo delo, nove datoteke, nove ideje, ljubezenska pisma, itd.).", + "", + "V tej lekciji se bomo naučili kako fetchat (prenesti) podatke iz oddaljenega repozitorija -- ukaz za to je poimenovan `git fetch`.", + "", + "Opazil boš, da ko posodobimo našo predstavitev oddaljenega repota, se bo naš oddaljen branch posodobil in imel nove spremembe. To se navezuje na prejšnjo lekcijo o oddaljenih repozitorijih." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Preden se spustimo v podrobnosti `git fetch` ga poglejmo v akciji! Tu imamo oddaljen repozitorij, ki vsebuje dva commita, ki jih naš lokalen repozitorij nima." + ], + "afterMarkdowns": [ + "Tako! Commita `C2` in `C3` sta bila prenesena v naš lokalen repozitorij in naš oddaljen branch `o/main` je bil posodobljen, da to odraža." + ], + "command": "git fetch", + "beforeCommand": "git clone; git fakeTeamwork 2" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Kaj fetch naredi", + "", + "`git fetch` naredi dve stvari. In sicer:", + "", + "* prenese commite, ki jih ima oddaljeni repo ampak manjkajo v našem lokalnem in ...", + "* posodobi, kam kaže naš oddaljeni branch (naprimer `o/main`)", + "", + "`git fetch` v bistvu našo lokalno predstavitev oddaljenega repozitorija uskladi z dejanskim stanjem na oddaljenem repozitoriju.", + "", + "Če se spomneš še iz prejšnje lekcije smo rekli, da oddaljeni branchi odsevajo stanje na oddaljenih repozitorijih, odkar si komuniciral z njimi. `git fetch` je način, da komuniciraš z njimi! Upam, da je sedaj povezava med oddaljenimi repozitoriji in `git fetch` jasna.", + "", + "`git fetch` ponavadi komunicira z oddaljenimi repozitoriji preko interneta (s protokolom kot sta `http://` ali `git://`).", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Kaj fetch ne naredi", + "", + "`git fetch` ne spremeni ničesar glede tvojega lokalnega stanja. Ne bo posodobil tvojega `main` brancha ali spremenil česarkoli v tvojih datotekah.", + "", + "To je pomembno razumeti, ker veliko razvijalcev misli, da bo `git fetch` posodobil njihovo lokalno stanje s stanjem na oddaljenem repozitoriju. Lahko bo prenesel vse potrebne podatke, da to izvede, ampak v bistvu _ne_ spremeni tvojih datotek. V kasnejših lekcijah se bomo naučili ukaze, ki pa naredijo točno to. :D", + "", + "Torej na koncu dneva, izvajanje `git fetch` si lahko predstavljate kot korak za prenašanje." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Za dokončanje te stopnje uporabi `git fetch` in prenesi vse commite!" + ] + } + } + ] } } }; diff --git a/src/levels/remote/fetchArgs.js b/src/levels/remote/fetchArgs.js index 405329c1..8f82cdc8 100644 --- a/src/levels/remote/fetchArgs.js +++ b/src/levels/remote/fetchArgs.js @@ -1,6 +1,6 @@ exports.level = { "goalTreeString": "{\"branches\":{\"master\":{\"target\":\"C6\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\"},\"foo\":{\"target\":\"C7\",\"id\":\"foo\",\"remoteTrackingBranchID\":\"o/foo\"},\"o/master\":{\"target\":\"C1\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null},\"o/foo\":{\"target\":\"C1\",\"id\":\"o/foo\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C2\"],\"id\":\"C3\"},\"C5\":{\"parents\":[\"C1\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C5\"],\"id\":\"C6\"},\"C7\":{\"parents\":[\"C3\",\"C6\"],\"id\":\"C7\"}},\"HEAD\":{\"target\":\"foo\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C4\",\"id\":\"master\",\"remoteTrackingBranchID\":null},\"foo\":{\"target\":\"C6\",\"id\":\"foo\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C2\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C3\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C1\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C5\"],\"id\":\"C6\"}},\"HEAD\":{\"target\":\"foo\",\"id\":\"HEAD\"}}}", - "solutionCommand": "git fetch origin master~1:foo;git fetch origin foo:master;git checkout foo;git merge master", + "solutionCommand": "git fetch origin main~1:foo;git fetch origin foo:main;git checkout foo;git merge main", "startTree": "{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\"},\"foo\":{\"target\":\"C1\",\"id\":\"foo\",\"remoteTrackingBranchID\":\"o/foo\"},\"o/master\":{\"target\":\"C1\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null},\"o/foo\":{\"target\":\"C1\",\"id\":\"o/foo\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"}},\"HEAD\":{\"target\":\"C1\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C4\",\"id\":\"master\",\"remoteTrackingBranchID\":null},\"foo\":{\"target\":\"C6\",\"id\":\"foo\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C2\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C3\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C1\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C5\"],\"id\":\"C6\"}},\"HEAD\":{\"target\":\"foo\",\"id\":\"HEAD\"}}}", "name": { "en_US": "Fetch arguments", @@ -8,12 +8,16 @@ exports.level = { "zh_CN": "Git fetch 的参数", "zh_TW": "fetch 的參數", "es_AR": "Parámetros de fetch", + "es_ES": "Parámetros de fetch", "pt_BR": "Parâmetros do fetch", + "gl" : "Parámetros de fetch", "de_DE": "Optionen für Fetch", "ja" : "Fetchの引数", "ru_RU": "Аргументы для fetch", "ko" : "Fetch의 인자들", - "uk" : "Аргументи для fetch" + "uk" : "Аргументи для fetch", + "vi" : "Tham số fetch", + "sl_SI": "Fetch argumenti" }, "hint": { "en_US": "Pay attention how the commit ids may have swapped! You can read slides again with \"help level\"", @@ -21,12 +25,16 @@ exports.level = { "zh_CN": "注意下提交对象的 id 是如何交换的! 你可以通过 `help level` 重新阅读本关卡的所有对话框!", "zh_TW": "注意 commit 的 id 是怎麼被交換的!你可以透過 `help level` 來閱讀對話視窗!", "es_AR": "¡Prestá atención a cómo podrían haberse invertido los ids de los commits! Podés volver a leer toda la lección usando \"help level\"", + "es_ES": "¡Presta atención a cómo podrían haberse invertido los ids de los commits! Puedes volver a leer toda la lección usando \"help level\"", "pt_BR": "Preste atenção em como os identificadores dos commits podem ter trocado! Você pode ler os slides novamente com \"help level\"", + "gl" : "Preste atención en como poderían invertirse os ids dos commits! Podes volver ler toda a lección usando \"help level\"", "de_DE": "Beachte wie die Commit IDs getauscht wurden! Du kannst den Einführungsdialog mit \"help level\" erneut anzeigen", "ja" : "コミットIDの入れ替わりに注意!スライドを復習するには`help level`を実行", "ru_RU": "Обратите внимание на то, как номера коммитов могут меняться! Вы можете прочесть слайды вновь, воспользовавшись командой \"help level\"", "ko" : "커밋 ID가 바뀔수도있으니 주의하세요! \"help level\"을 입력하면 슬라이드들을 다시 읽어볼수 있습니다.", - "uk" : "Зверни увагу на те, що номери комітів можуть змінюватися! Слайди уроку можна переглянути ще раз командою \"help level\"" + "uk" : "Зверни увагу на те, що номери комітів можуть змінюватися! Слайди уроку можна переглянути ще раз командою \"help level\"", + "vi" : "Lưu ý id của các commit bị tráo đổi, bạn có thể dùng \"help level\" để đọc lại hội thoại", + "sl_SI": "Bodi pozoren kako so se commit id-ji morda zamenjali! Ponovno lahko prebereš navodila z \"help level\"." }, "startDialog": { "en_US": { @@ -68,7 +76,7 @@ exports.level = { "By specifying a place..." ], "afterMarkdowns": [ - "We download only the commits from `foo` and place them on `o/foo`" + "We download only the commits from `foo` and place them on `o/foo`." ], "command": "git fetch origin foo", "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo 2" @@ -137,7 +145,7 @@ exports.level = { "Pretty simple, but worth going over just once." ], "command": "git fetch", - "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo; git fakeTeamwork master" + "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo; git fakeTeamwork main" } }, { @@ -260,7 +268,7 @@ exports.level = { "Assez simple, mais ce n'était pas inutile de voir en action." ], "command": "git fetch", - "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo; git fakeTeamwork master" + "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo; git fakeTeamwork main" } }, { @@ -314,7 +322,7 @@ exports.level = { "Especificando un lugar..." ], "afterMarkdowns": [ - "Sólo bajamos los commits de `foo` y los ubicamos en `o/foo`" + "Sólo bajamos los commits de `foo` y los ubicamos en `o/foo`." ], "command": "git fetch origin foo", "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo 2" @@ -341,7 +349,7 @@ exports.level = { "", "Este es el único problemita, igual: `` es ahora un lugar en el *remoto*, y `` es un lugar *local* en donde poner esos commits. Es exactamente lo opuesto a git push, y eso tiene sentido dado que ¡estamos transfiriendo los datos en la dirección opuesta!", "", - "Habiendo dicho esto, dificilmente alguien use esto en la práctica. Lo estoy presentando principalmente como un modo de conceptualizar que `fetch` y `push` son bastante similares, sólo que en direcciones opuestas." + "Habiendo dicho esto, difícilmente alguien use esto en la práctica. Lo estoy presentando principalmente como un modo de conceptualizar que `fetch` y `push` son bastante similares, sólo que en direcciones opuestas." ] } }, @@ -383,7 +391,7 @@ exports.level = { "Bastante simple, pero vale la pena verlo al menos una vez." ], "command": "git fetch", - "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo; git fakeTeamwork master" + "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo; git fakeTeamwork main" } }, { @@ -398,6 +406,129 @@ exports.level = { } ] }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Parámetros de git fetch", + "", + "Acabamos de aprender todo sobre los parámetros de push, como el parámetro ``, e incluso las referencias separadas por dos puntos (`:`). ¿Podremos usar todo ese conocimiento para `git fetch`, también?", + "", + "¡Dalo por hecho! Los parámetros para `git fetch` son realmente *muy, muy* similares a los de `git push`. Es el mismo tipo de conceptos, pero aplicados en la dirección opuesta (dado que ahora estás bajando commits en lugar de subirlos).", + "", + "Veamos los conceptos de a uno en uno..." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### El parámetro ``", + "", + "Si especificas un lugar con git fetch como en el comando siguiente:", + "", + "`git fetch origin foo`", + "", + "Git va a ir a la rama `foo` en el remoto, va a traer todos los commits que no estén presentes localmente, y luego los aplicará sobre la rama `o/foo` localmente.", + "", + "Veámoslo en acción (refresquemos el concepto)." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Especificando un lugar..." + ], + "afterMarkdowns": [ + "Sólo bajamos los commits de `foo` y los ubicamos en `o/foo`." + ], + "command": "git fetch origin foo", + "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo 2" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Te podrás estar preguntando \"¿Por qué git aplicó esos commits sobre la rama `origin/foo` en lugar de aplicarlos sobre la rama `foo` local? Pensé que el parámetro `` era un lugar que existía tanto local como remotamente\"", + "", + "Bueno, git hace una excepción especial en este caso, porque podrías tener trabajo en la rama `foo` que no quieras mezclar. Esto hace referencia a la lección anterior sobre `git fetch` - no actualiza tus ramas locales no-remotas, sólo descarga los commits (para que pueadas verlos o mergearlos después).", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "\"Bueno, y, en ese caso, ¿qué pasa si explícitamente defino el origen y destino con `:`?\"", + "", + "Si te sientes lo suficientemente seguro como para traer commits *directamente* a una rama local, entonces, sí, puedes especificarlo usando una referencia con dos puntos. No puedes traer commits a una rama que sobre la que hayas hecho checkout, pero en cualquier otro caso git te lo va a permitir.", + "", + "Este es el único problema, igual: `` es ahora un lugar en el *remoto*, y `` es un lugar *local* en donde poner esos commits. Es exactamente lo opuesto a git push, y eso tiene sentido dado que ¡estamos transfiriendo los datos en la dirección opuesta!", + "", + "Habiendo dicho esto, difícilmente alguien use esto en la práctica. Lo estoy presentando principalmente como un modo de conceptualizar que `fetch` y `push` son bastante similares, sólo que en direcciones opuestas." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Veamos esta locura en acción:" + ], + "afterMarkdowns": [ + "¡Caramba! Mira: git resolvió `foo~1` como un lugar en el origin y bajó esos commits a `bar` (que era una rama local). Observa como `foo` y `o/foo` no fueron actualizados, dado que especificamos un destino." + ], + "command": "git fetch origin foo~1:bar", + "beforeCommand": "git branch foo; git clone; git branch bar; git fakeTeamwork foo 2" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "¿Qué pasa si el destino no existe antes de ejecutar este comando? Veamos el último ejemplo pero sin que `bar` exista de antemano." + ], + "afterMarkdowns": [ + "Mira: es IGUAL que git push. Git creó el destino localmente antes de hacer el fetch, tal como git creará el destino en el remoto antes de hacer push (si no existiera)." + ], + "command": "git fetch origin foo~1:bar", + "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo 2" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "¿Sin argumentos?", + "", + "Si `git fetch` no recibe ningún argumento, simplemente descarga todos los commits del remoto a todas las ramas remotas..." + ], + "afterMarkdowns": [ + "Bastante simple, pero merece la pena verlo al menos una vez." + ], + "command": "git fetch", + "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo; git fakeTeamwork main" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Bueno, demasiada charla. Para completar este nivel, haz fetch sólo de los commits especificados en la visualización del objetivo. ¡Familiarízate con esos comandos!", + "", + "Vas a tener que especificar el origen y el destino para ambos comandos fetch. Presta atención al objetivo dado que ¡los IDs pueden estar invertidos!" + ] + } + } + ] + }, "pt_BR": { "childViews": [ { @@ -437,7 +568,7 @@ exports.level = { "Especificando um lugar..." ], "afterMarkdowns": [ - "Baixamos só os commits de `foo` e colocamos em `o/foo`" + "Baixamos só os commits de `foo` e colocamos em `o/foo`." ], "command": "git fetch origin foo", "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo 2" @@ -506,7 +637,7 @@ exports.level = { "Bastante simples, mas importante de rever ao menos uma vez." ], "command": "git fetch", - "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo; git fakeTeamwork master" + "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo; git fakeTeamwork main" } }, { @@ -521,6 +652,129 @@ exports.level = { } ] }, + "gl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Parámetros de fetch", + "", + "Entonces, aprendido todo sobre os parámetros de push, este parámetro `` molón, e incluso as referencias separadas por dous puntos (`:`). ¿Poderemos empregar todo este coñecemento para `git fetch` tamén?", + "", + "¡Home claro! Os parámetros para `git fetch` son realmente *moi, moi* semellantes os de `git push`. É o mesmo tipo de conceptos, pero aplicados na dirección contraria (xa que agora estás baixando os commits en lugar de subilos).", + "", + "Vexamos os conceptos dunha puntada..." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### O parámetro ``", + "", + "Se especificar o lugar co git fetch como no comando seguinte:", + "", + "`git fetch origin foo`", + "", + "Git vai ir á rama `foo` no remoto, vai traer tódolos commits que non estén presentes localmente, e logo aplicaráos sobre a rama `o/foo` localmente.", + "", + "Vexámolo en acción (refresquemos o concepto)." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Especificando un lugar..." + ], + "afterMarkdowns": [ + "Sólo baixamos os commits de `foo` e os poñemos en `o/foo`." + ], + "command": "git fetch origin foo", + "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo 2" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Poderás preguntarte \"¿Por qué git aplicou eses commits sobre a rama `origin/foo` e non os aplicou sobre a rama `foo` local? Lembra que o parámetro `` era un lugar que existía tanto no local como no remoto.\"", + "", + "Bueno, git fai unha excepción especial neste caso, xa que poderías ter traballo na rama `foo` que non quixeras mesturar. Esto refírese á lección anterior sobre `git fetch` - non actualiza as túas ramas locais non-remotas, só descarga os commits (para que poidas velos ou mesturalos despois).", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "\"Bueno, e, neste caso, ¿qué pasa se explícitamente definimos o orixe e destino con `:`?\"", + "", + "Se te sentes o suficientemente seguro como para traer os commits *directamente* da rama local, entón, sí, podes especificalo empregando a referencia con dous puntos. Non podes traer commits a unha rama que non teñas, pero en calquera outro caso, git vaino facer.", + "", + "Este é o único problema, igual: `` é agora un lugar no *remoto*, e `` é un lugar *local* onde poñer esos commits. É exactamente o oposto a git push, e eso ten sentido xa que ¡estamos enviando os datos no sentido contrario!", + "", + "Dito esto, difícilmente alguén use esto na práctica. Estouno presentando principalmente como un modo de traballar no que `fetch` e `push` son moi semellantes, só que en direccións opostas." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Vexamos esta locura en acción" + ], + "afterMarkdowns": [ + "¡Wow! Mira: git resolveu `foo~1` como un lugar no que a orixe descargou eses commits a `bar` (que era unha rama local). Nota como `foo` e `o/foo` non foron actualizados, xa que especificamos o destino." + ], + "command": "git fetch origin foo~1:bar", + "beforeCommand": "git branch foo; git clone; git branch bar; git fakeTeamwork foo 2" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "¿Qué pasa si o destino non existe antes de lanzar este comando? Vexamos o último exemplo pero sin que `bar` exista de antemán." + ], + "afterMarkdowns": [ + "Mira: é IGUAL que git push. Git creou o destino localmente antes de facer o fetch, tal e como git creará o destino no remoto antes de empurrar (se non existiran)." + ], + "command": "git fetch origin foo~1:bar", + "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo 2" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "¿Sen argumentos?", + "", + "Se `git fetch` non recibe ningún argumento, simplemente descarga tódolos commits do remoto a tódalas ramas remotas..." + ], + "afterMarkdowns": [ + "Moi sinxelo, pero vale a pena velo ó menos unha vez." + ], + "command": "git fetch", + "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo; git fakeTeamwork main" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Bueno, moitas verbas. Para rematar o nivel, descarga só os commits especificados na visualización do obxectivo. ¡Faite colega destes comandos!", + "", + "Vas ter que especificar a orixe e o destino para ámbolos dous comandos fetch. Presta atención ó objetivo dado que ¡os IDs poden estar invertidos!" + ] + } + } + ] + }, "zh_TW": { "childViews": [ { @@ -629,7 +883,7 @@ exports.level = { "超簡單,但是所有的更新只做一次,很值得。" ], "command": "git fetch", - "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo; git fakeTeamwork master" + "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo; git fakeTeamwork main" } }, { @@ -752,7 +1006,7 @@ exports.level = { "相当简单,但是仅需更新一次,值得你去做!" ], "command": "git fetch", - "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo; git fakeTeamwork master" + "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo; git fakeTeamwork main" } }, { @@ -775,11 +1029,11 @@ exports.level = { "markdowns": [ "## Git Fetch Optionen", "", - "Nun haben wir also alles über `git push` Optionen gelernt, diesen coolen ``-Parameter, and sogar über mit Doppelpunkt getrennte Ref-Spezifikationen (`:`). Können wir all dieses neu erworbene Wissen auch auf `git fetch` anwenden?", + "Nun haben wir also alles gelernt über `git push` Optionen, diesen coolen ``-Parameter und sogar mit Doppelpunkt getrennte Ref-Spezifikationen (`:`). Können wir all dieses neu erworbene Wissen auch auf `git fetch` anwenden?", "", "Jede Wette! Die Optionen für `git fetch` sind wirklicht *sehr, sehr* ähnlich denen von `git push`. Es sind dieselben Verfahren, nur in die andere Richtung angewendet (da man bei `fetch` herunterlädt anstatt hochzuladen).", "", - "Gehen wir die verschiedenen Verfahrensweise mal eine nach der anderen durch ..." + "Gehen wir die verschiedenen Verfahrensweisen mal eine nach der anderen durch ..." ] } }, @@ -795,7 +1049,7 @@ exports.level = { "", "wird Git zum Branch `foo` auf dem Remote gehen, dort alle Änderungen holen, die es lokal noch nicht gibt, und sie an den lokalen Branch `o/foo` anhängen.", "", - "Schauen wir uns das mal live an (nur zur Wiederholung)" + "Schauen wir uns das mal live an (nur zur Wiederholung)." ] } }, @@ -816,9 +1070,9 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Du wunderst dich vielleicht warum Git diese Commits auf den `o/foo` Branch gepacht hat, anstatt einfach direkt auf den lokalen Branch `foo`? Zeigt der Parameter `` nicht einen Ort an, der sowohl lokal als auch entfernt existiert?", + "Du wunderst dich vielleicht, warum Git diese Commits auf den `o/foo` Branch gepackt hat, anstatt einfach direkt auf den lokalen Branch `foo`? Zeigt der Parameter `` nicht einen Ort an, der sowohl lokal als auch entfernt existiert?", "", - "Nun ja, Git geht diesen Schritt weil du auf `foo` ja noch Commits haben könntest, die nicht auf dem Server sind, und da will es nichts durcheinander bringen. Ähnlich wie beim früheren Level zu `git fetch` -- es aktualisiert nicht deine lokalen Arbeits-Branches, es lädt die Commits nur in die `o` (bzw. `origin`) Branches, damit du sie dir in Ruhe anschauen und integrieren kannst.", + "Nun ja, Git geht diesen Schritt, weil du auf `foo` ja noch Commits haben könntest, die nicht auf dem Server sind, und da will es nichts durcheinander bringen. Ähnlich wie beim früheren Level zu `git fetch` -- es aktualisiert nicht deine lokalen Arbeits-Branches, es lädt die Commits nur in die `o` (bzw. `origin`) Branches, damit du sie dir in Ruhe anschauen und integrieren kannst.", "" ] } @@ -829,7 +1083,7 @@ exports.level = { "markdowns": [ "Wenn das so ist, was passiert dann wenn ich explizit Quelle und Ziel im Ort angebe?", "", - "Wenn du Commits wirklich per `fetch` *direkt* auf einen lokalen Branch holen willst, dann, ja, kannst du das mit einer Ref-Spezifikation erreichen. Das funktioniert nicht mit deinem gerade ausgecheckten Branch, aber davon abgesehen lässt Git es zu.", + "Wenn du Commits wirklich per `fetch` *direkt* auf einen lokalen Branch holen willst, dann kannst du das mit einer Ref-Spezifikation erreichen. Das funktioniert nicht mit deinem gerade ausgecheckten Branch, aber davon abgesehen lässt Git es zu.", "", "Nur ein Haken -- `` bezeichnet jetzt einen Ort auf dem *entfernten* Server und `` ist ein *lokaler* Ort, wo die Commits hin sollen. Es ist genau umgekehrt wie bei `git push` und das ist logisch, denn wir übertragen die Daten ja auch in die umgekehrte Richtung!", "", @@ -844,7 +1098,7 @@ exports.level = { "Schauen wir uns den Quatsch mal in Aktion an:" ], "afterMarkdowns": [ - "Wow! Siehst du, git löst `foo~1` als Ort auf dem Server `origin` auf und lädt dessen Commits herunter in `bar` hinein. Beachte wie `foo` und `o/foo` *nicht* aktualisiert wurden, da wir ein Ziel angegeben haben." + "Wow! Siehst du, Git löst `foo~1` als Ort auf dem Server `origin` auf und lädt dessen Commits herunter in `bar` hinein. Beachte wie `foo` und `o/foo` *nicht* aktualisiert wurden, da wir ein Ziel angegeben haben." ], "command": "git fetch origin foo~1:bar", "beforeCommand": "git branch foo; git clone; git branch bar; git fakeTeamwork foo 2" @@ -854,10 +1108,10 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Was ist denn wenn das Ziel nicht existiert, für das ich den Befehl ausführe? Schauen wir uns das letzte Beispiel noch mal an, nur dass `bar` jetzt noch nicht existiert." + "Was ist denn, wenn das Ziel nicht existiert, für das ich den Befehl ausführe? Schauen wir uns das letzte Beispiel noch mal an, nur dass `bar` jetzt noch nicht existiert." ], "afterMarkdowns": [ - "Siehst du, es ist *genau* wie `git push`. Git erstellt das Ziel lokal bevor es den `fetch` ausführt, genauso wie Git erst das Ziel auf dem Remote erstellt, befor es pusht (falls das Ziel nicht existiert)." + "Siehst du, es ist *genau* wie `git push`. Git erstellt das Ziel lokal bevor es den `fetch` ausführt, genauso wie Git erst das Ziel auf dem Remote erstellt, bevor es pusht (falls das Ziel nicht existiert)." ], "command": "git fetch origin foo~1:bar", "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo 2" @@ -875,7 +1129,7 @@ exports.level = { "Ziemlich einfach, aber man sollte es mal gesehen haben." ], "command": "git fetch", - "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo; git fakeTeamwork master" + "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo; git fakeTeamwork main" } }, { @@ -929,7 +1183,7 @@ exports.level = { "Указывая пункт назначения..." ], "afterMarkdowns": [ - "мы скачиваем только коммиты с ветки `foo` и помещаем их в `o/foo`" + "мы скачиваем только коммиты с ветки `foo` и помещаем их в `o/foo`." ], "command": "git fetch origin foo", "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo 2" @@ -998,7 +1252,7 @@ exports.level = { "Достаточно просто, после того как мы пережили все эти технические тонкости." ], "command": "git fetch", - "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo; git fakeTeamwork master" + "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo; git fakeTeamwork main" } }, { @@ -1121,7 +1375,7 @@ exports.level = { "간단하지만, 짚고 넘어갑시다." ], "command": "git fetch", - "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo; git fakeTeamwork master" + "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo; git fakeTeamwork main" } }, { @@ -1175,7 +1429,7 @@ exports.level = { "Вказуючи ``..." ], "afterMarkdowns": [ - "Ми звантажуємо коміти лише з `foo` і кладемо їх в `o/foo`" + "Ми звантажуємо коміти лише з `foo` і кладемо їх в `o/foo`." ], "command": "git fetch origin foo", "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo 2" @@ -1244,7 +1498,7 @@ exports.level = { "Все дуже просто, але варто було згадати ще раз." ], "command": "git fetch", - "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo; git fakeTeamwork master" + "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo; git fakeTeamwork main" } }, { @@ -1258,6 +1512,252 @@ exports.level = { } } ] + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Tham số Git fetch", + "", + "Chúng ta vừa tìm hiểu về tham số của git push, sự tuyệt vời của tham số ``, và thậm chí cả refspecs (`:<đích>`). Liệu ta có thể áp dụng điều này vào `git fetch` không nhỉ?", + "", + "Đoán chuẩn rồi đấy! Tham số cho lệnh `git fetch` thực ra *rất, rất* giống với `git push`. Chúng có chung khái niệm nhưng được áp dụng cho hướng ngược lại(vì bây giờ ta tải xuống commit chứ không phải tải lên).", + "", + "Hãy lần lượt đi qua từng khái niệm một..." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Tham số ``", + "", + "Nếu bạn chỉ định vị trí cho `git fetch` như câu lệnh dưới:", + "", + "`git fetch origin foo`", + "", + "Git sẽ lênh nhánh `foo` trên kho chứa từ xa, lấy toàn bộ các commit chưa có trên kho chứa cục bộ và thả chúng xuống nhánh `o/foo` ở kho chứa cục bộ.", + "", + "Hãy xem một ví dụ (vẫn là câu lệnh trên nhưng mà trực quan hơn)." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Thông qua chỉ định vị trí..." + ], + "afterMarkdowns": [ + "Ta chỉ tải xuống commit ở trên nhánh `foo` và đặt chúng ở nhánh `o/foo`." + ], + "command": "git fetch origin foo", + "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo 2" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Có thể bạn sẽ thắc mắc -- tại sao git lại thả các commit xuống nhánh `o/foo` thay vì nhánh `foo` ở kho chứa cục bộ? Tôi tưởng tham số `` tồn tại ở cả kho chứa cục bộ và kho chứa từ xa mà?", + "", + "Chà trong trường hợp này git ứng xử có một chút ngoại lệ đặc biệt, vì có thể bạn đang làm việc trên nhánh `foo` ở kho chứa cục bộ mà bạn không muốn nó bị làm rối!! Điều này liên kết đến bài học trước về `git fetch` -- nó không cập nhật nhánh cục bộ không liên kết nhánh từ xa của bạn(nhánh không có tiền tố `origin/`), nó chỉ tải xuống các commit( mà bạn có thể xem xét hoặc hợp nhất sau).", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "\"Nếu vậy, thì điều gì sẽ xảy ra nếu tôi chỉ định cả nguồn và đích với `:<đích>`?\"", + "", + "Nếu bạn nhất quyết muốn tải commit *trực tiếp* xuống nhánh cục bộ,thì bạn có thể chỉ định điều này bằng cách dùng refspec hai chấm. Bạn không thể nạp commit vào nhánh mà bạn đang đứng, nhưng git sẽ cho phép bạn làm điều này:", + "", + "Đây là cách duy nhất -- `` là vị trí trên kho *từ xa* và `<đích>` là vị trí *cục bộ* để đặt các commit. Điều này hoàn toàn ngược lại với `git push`, và đó là tất nhiên thôi vì ta đang chuyển giao dữ liệu theo hướng ngược lại!", + "", + "Thực tế là, các nhà phát triển rất hiếm khi làm điều này. Tôi giới thiệu về nó chủ yếu là vì muốn giải thích rõ hơn việc `fetch` và `push` là khá tương đồng, chỉ là theo hướng ngược lại." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Lấy một ví dụ điên rồ..." + ], + "afterMarkdowns": [ + "Wao! Thấy chứ, git diễn giải `foo~1` thành một vị trí trên kho chứa từ xa sau đó tải xuống các commit lên nhánh `bar` ở kho chứa cục bộ. Để ý rằng nhánh `foo` và `o/foo` không hề được cập nhật vì ta đã chỉ định đích đến." + ], + "command": "git fetch origin foo~1:bar", + "beforeCommand": "git branch foo; git clone; git branch bar; git fakeTeamwork foo 2" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Nếu như đích đến chưa hề tồn tại trước khi tôi chạy lệnh thì sao? Cùng xem lại ví dụ vừa rồi nhưng lần này nhánh `bar` chưa hề tồn tại." + ], + "afterMarkdowns": [ + "Thấy chứ, nó Y HỆT với git push. Git tạo ra đích đến ở kho chứa cục bộ trước khi nạp, cũng giống như git sẽ tạo ra đích đến trên kho chứa từ xa trước khi đẩy (trong trường hợp nó không tồn tại)." + ], + "command": "git fetch origin foo~1:bar", + "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo 2" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Không có tham số?", + "", + "Nếu lệnh `git fetch` không nhận được bất kỳ tham số nào, nó sẽ tải xuống tất cả các commit có trên kho chứa từ xa lên tất cả các nhánh từ xa ở kho chứa cục bộ..." + ], + "afterMarkdowns": [ + "Khá là đơn giản, nhưng mà cũng nên xem qua thử." + ], + "command": "git fetch", + "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo; git fakeTeamwork main" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Được rồi, lý thuyết như vậy là đủ rồi! Để hoàn thành cấp độ này, hãy chỉ nạp những commit được chỉ định trong mô tả mục tiêu. Thoải mái ứng biến với những câu lệnh nhé!", + "", + "Bạn sẽ phải chỉ định nguồn và dích cho lệnh fetch. Chú ý đến mô tả mục tiêu vì các ID có thể bị xáo trộn!" + ] + } + } + ] + }, + "sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git fetch argumenti", + "", + "Torej pravkar smo se naučili vse o git push argumentih ter kul `` parameteru in celo dvopični referenci (`:`). Torej uporabimo vse znanje tudi za `git fetch`?", + "", + "Itak! Argumenti za `git fetch` so v bistvu *zelo zelo* podobni tistim za `git push`. Gre za enak koncept, ampak uporabljen v nasprotni smeri (ker sedaj prenašamo commite, namesto da jih nalagamo).", + "", + "Pojdimo čez koncepte drug za drugim ..." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### `` parameter", + "", + "Če podaš mesto poleg git fetcha kot v naslednjem ukazu:", + "", + "`git fetch origin foo`", + "", + "Bo Git šel na `foo` branch na oddaljenem repotu, pograbil vse commite, katerih lokalno še nimamo in jih dodal na dno lokalnega `o/foo` brancha.", + "", + "Poglejmo to v akciji (samo kot osvežitev)." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Z določanjem mesta ..." + ], + "afterMarkdowns": [ + "Prenesemo samo commite iz `foo` in jih postavimo na `o/foo`." + ], + "command": "git fetch origin foo", + "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo 2" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Morda se sprašuješ -- zakaj je git dodal te commite na `o/foo` oddaljen branch namesto, da bi jih dodal na moj lokalen `foo` branch? Mislil sem, da je `` parameter mesto, ki obstaja in lokalno in na oddaljenem repozitoriju?", + "", + "No, git naredi v tem primeru posebno izjemo, ker imaš morda delo na `foo` branchu, ki ga ne želiš pokvariti!! To se navezuje na prejšnjo lekcijo o `git fetch` -- ne posodobi tvojega lokalnega ne-oddaljenega brancha, samo prenese commite (da jih lahko pregledaš / mergaš kasneje).", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "\"Ampak v tem primeru, kaj se zgodi, če posebaj določim izvor in cilj s `:`?\"", + "", + "Če se počutiš dovolj strastno, da bi fetchal commite *direktno* na lokalen branch, potem ja, lahko to definiraš z dvopično referenco. Ne moreš fetchati commitov na branch, ki je checkoutan, ampak v drugih primerih to lahko narediš.", + "", + "Tu je edina zanka -- `` je sedaj mesto na *oddaljenem* in `` je *lokalno* mesto za dodati te commite. Je ravno nasprotje od git pusha in to je logično, saj prenašamo podatke v nasprotni smeri!", + "", + "Glede na to, razvijalci to redko delajo v praksi, to predstavljam zgolj, da si lahko predstavljaš, kako sta si `fetch` in `push` kar podobna, ampak v nasprotni smeri." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Poglejmo si to zmešnjavo v praksi:" + ], + "afterMarkdowns": [ + "Wow! Vidiš, git je naredil `foo~1` kot mesto na originu in nato prenesel commite na `bar` (ki je bil lokalen branch). Opazi, kako `foo` in `o/foo` nista bila posodobljena, ker smo določili destinacijo." + ], + "command": "git fetch origin foo~1:bar", + "beforeCommand": "git branch foo; git clone; git branch bar; git fakeTeamwork foo 2" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Kaj pa, če destinacija ne obstaja, preden zaženem ukaz? Poglejmo zadnji primer, vendar brez da bi prej `bar` že obstajal." + ], + "afterMarkdowns": [ + "Vidiš, je TAKO kot git push. Git je naredil destinacijo lokalno pred fetchem, tako kot bo naredil destinacijo na oddaljneme repotu pred pushem (če ne obstaja)." + ], + "command": "git fetch origin foo~1:bar", + "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo 2" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Ni argumentov?", + "", + "Če `git fetch` ne prejme argumentov, prenese vse commite iz oddaljenega repota na vse oddaljene branche ..." + ], + "afterMarkdowns": [ + "Precej enostavno, ampak vredno, da gremo čez vsaj enkrat." + ], + "command": "git fetch", + "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo; git fakeTeamwork main" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Ok, dovolj govorjenja! Da zaključiš to stopnjo, fetchaj samo določene commite iz ciljne vizualizacije. Razturaj te ukaze!", + "", + "Določiti boš moral izvor in cilj za oba fetch ukaza. Bodi pozoren na ciljno vizualizacijo, saj so lahko IDji obrnjenji okoli!" + ] + } + } + ] } } }; diff --git a/src/levels/remote/fetchRebase.js b/src/levels/remote/fetchRebase.js index 851316bd..a409a2cf 100644 --- a/src/levels/remote/fetchRebase.js +++ b/src/levels/remote/fetchRebase.js @@ -7,26 +7,34 @@ exports.level = { "zh_CN": "偏离的提交历史", "zh_TW": "diverged history", "es_AR": "Historia divergente", + "es_ES": "Historia divergente", "pt_BR": "Histórico divergente", + "gl" : "Histórico diverxente", "de_DE": "Abweichende History", "fr_FR": "Historique divergent", "ja" : "履歴の分岐", "ru_RU": "Расхождение в истории", "uk" : "Розбіжності в історії", - "ko" : "엇갈린 히스토리" + "ko" : "엇갈린 히스토리", + "vi" : "Dị biệt lịch sử", + "sl_SI": "Razdeljena Zgodovina" }, "hint": { "en_US": "check out the ordering from the goal visualization", "zh_CN": "按照目标中的提交树的顺序进行检出", "zh_TW": "確認視覺化的目標中的順序", "es_AR": "Prestá atención al orden del objetivo", + "es_ES": "Presta atención al orden del objetivo", "pt_BR": "Preste atenção na ordem da visualização do objetivo", + "gl" : "Presta atención ó orixe do obxectivo", "de_DE": "Beachte die Reihenfolge in der Zieldarstellung", "ja" : "ゴールのツリーの順番を参考にすること", "fr_FR": "regardez l'ordre dans la fenêtre de visualisation d'objectif", "ru_RU": "проверьте сортировку в визуализации цели", "uk" : "перевірте порядок в візуалізації цілі", - "ko" : "순서는 goal을 참고하세요" + "ko" : "순서는 goal을 참고하세요", + "vi" : "kiểm tra kỹ thứ tự trên mô hình mục tiêu", + "sl_SI": "Preveri vrstni red iz ciljne vizualizacije." }, "startDialog": { "en_US": { @@ -60,10 +68,10 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "So much talking! Let's see this situation in action" + "So much talking! Let's see this situation in action." ], "afterMarkdowns": [ - "See? Nothing happened because the command fails. `git push` fails because your most recent commit `C3` is based off of the remote at `C1`. The remote has since been updated to `C2` though, so git rejects your push" + "See? Nothing happened because the command fails. `git push` fails because your most recent commit `C3` is based off of the remote at `C1`. The remote has since been updated to `C2` though, so git rejects your push." ], "command": "git push", "beforeCommand": "git clone; git fakeTeamwork; git commit" @@ -86,9 +94,9 @@ exports.level = { "Now if we rebase before pushing instead..." ], "afterMarkdowns": [ - "Boom! We updated our local representation of the remote with `git fetch`, rebased our work to reflect the new changes in the remote, and then pushed them with `git push`" + "Boom! We updated our local representation of the remote with `git fetch`, rebased our work to reflect the new changes in the remote, and then pushed them with `git push`." ], - "command": "git fetch; git rebase o/master; git push", + "command": "git fetch; git rebase o/main; git push", "beforeCommand": "git clone; git fakeTeamwork; git commit" } }, @@ -111,9 +119,9 @@ exports.level = { "Now if we merge instead of rebasing..." ], "afterMarkdowns": [ - "Boom! We updated our local representation of the remote with `git fetch`, *merged* the new work into our work (to reflect the new changes in the remote), and then pushed them with `git push`" + "Boom! We updated our local representation of the remote with `git fetch`, *merged* the new work into our work (to reflect the new changes in the remote), and then pushed them with `git push`." ], - "command": "git fetch; git merge o/master; git push", + "command": "git fetch; git merge o/main; git push", "beforeCommand": "git clone; git fakeTeamwork; git commit" } }, @@ -146,7 +154,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "And now with regular `pull`" + "And now with regular `pull`." ], "afterMarkdowns": [ "Again, exact same as before!" @@ -231,7 +239,7 @@ exports.level = { "afterMarkdowns": [ "Boum ! Nous avons mis à jour notre représentation locale du dépôt avec `git fetch`, rebasé notre travail pour refléter les nouveaux changements, et enfin les avons envoyés avec `git push`." ], - "command": "git fetch; git rebase o/master; git push", + "command": "git fetch; git rebase o/main; git push", "beforeCommand": "git clone; git fakeTeamwork; git commit" } }, @@ -256,7 +264,7 @@ exports.level = { "afterMarkdowns": [ "Boum ! Nous avons mis à jour notre représentation locale du dépôt distant avec `git fetch`, *fusionné* les nouveaux commits dans notre copie de travail (pour refléter les nouveaux changements du dépôt distant), et les avons ensuite envoyés avec `git push`." ], - "command": "git fetch; git merge o/master; git push", + "command": "git fetch; git merge o/main; git push", "beforeCommand": "git clone; git fakeTeamwork; git commit" } }, @@ -302,7 +310,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Cette succession de fetch, rebase/merge, et push est assez commune. Dans les leçons suivantes, nous explorerons cette façon de d'enchaîner les commandes dans des conditions plus complexes, mais pour le moment appliquons ce principe de façon classique.", + "Cette succession de fetch, rebase/merge, et push est assez commune. Dans les leçons suivantes, nous explorerons cette façon d'enchaîner les commandes dans des conditions plus complexes, mais pour le moment appliquons ce principe de façon classique.", "", "Pour finir ce niveau, réalisez les étapes suivantes :", "", @@ -349,7 +357,7 @@ exports.level = { "¡Demasiada charla, veámoslo en acción!" ], "afterMarkdowns": [ - "¿Ves? No pasó nada, porque el comando falla. `git push` falla porque `C3`, tu commit más reciente, está basado en el remoto sobre `C1`. El remoto fue actualizado a `C2` desde entonces, por lo que git rechaza tu push" + "¿Ves? No pasó nada, porque el comando falla. `git push` falla porque `C3`, tu commit más reciente, está basado en el remoto sobre `C1`. El remoto fue actualizado a `C2` desde entonces, por lo que git rechaza tu push." ], "command": "git push", "beforeCommand": "git clone; git fakeTeamwork; git commit" @@ -372,9 +380,9 @@ exports.level = { "Ahora, si mejor rebaseamos antes de pushear..." ], "afterMarkdowns": [ - "¡Boom! Actualizamos nuestra representación local del remoto con `git fetch`, rebaseamos nuestro trabajo para reflejar los nuevos cambios del remoto, y después los pusheamos con `git push`" + "¡Boom! Actualizamos nuestra representación local del remoto con `git fetch`, rebaseamos nuestro trabajo para reflejar los nuevos cambios del remoto, y después los pusheamos con `git push`." ], - "command": "git fetch; git rebase o/master; git push", + "command": "git fetch; git rebase o/main; git push", "beforeCommand": "git clone; git fakeTeamwork; git commit" } }, @@ -397,9 +405,9 @@ exports.level = { "Si en lugar de rebasear hacemos un merge..." ], "afterMarkdowns": [ - "¡Boom! Actualizamos nuestra representación local del remoto usando `git fetch`, *mergeamos* el nuevo trabajo junto con el nuestro (para reflejar los nuevos cambios en el remoto), y después los pusheamos usando `git push`" + "¡Boom! Actualizamos nuestra representación local del remoto usando `git fetch`, *mergeamos* el nuevo trabajo junto con el nuestro (para reflejar los nuevos cambios en el remoto), y después los pusheamos usando `git push`." ], - "command": "git fetch; git merge o/master; git push", + "command": "git fetch; git merge o/main; git push", "beforeCommand": "git clone; git fakeTeamwork; git commit" } }, @@ -458,6 +466,149 @@ exports.level = { } ] }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Trabajo divergente", + "", + "Hasta ahora hemos visto cómo hacer pull a commits de otros y cómo hacer push a los nuestros. Parece bastante simple, así que ¿cómo puede confundirse tanto la gente?", + "", + "La dificultad viene cuando la historia de los repositorios *diverge*. Antes de entrar en detalles, veamos un ejemplo...", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Imagínate que clonas un repositorio el lunes y empiezas a desarrollar algo. Para el viernes ya estás listo para publicar tu trabajo, pero, ¡vaya! Tus colegas también han estado escribiendo código durante la semana, haciendo que tu trabajo quede desactualizado (y obsoleto). Además, ellos publicaron esos commits en el repositorio remoto, así que ahora *tu* trabajo está basado en una versión *vieja* del proyecto, que ya no le interesa a nadie.", + "", + "En este caso, el comando `git push` es ambiguo. Si ejecutas `git push`, ¿git debería cambiar el repositorio a como estaba el lunes? ¿Debería tratar de agregar tu código sin eliminar el código nuevo? ¿O debería ignorar completamente tus cambios porque están desactualizados?", + "", + "Como hay tanta ambiguedad en esta situación (en la que la historia divirgió), git no te permite hacer push de tus cambios. En cambio, te fuerza a integrar el último estado del repositorio remoto antes de poder compartir tu trabajo." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "¡Demasiada charla, veámoslo en acción!" + ], + "afterMarkdowns": [ + "¿Ves? No pasó nada, porque el comando falla. `git push` falla porque `C3`, tu commit más reciente, está basado en el remoto sobre `C1`. El remoto fue actualizado a `C2` desde entonces, por lo que git rechaza tu push." + ], + "command": "git push", + "beforeCommand": "git clone; git fakeTeamwork; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "¿Cómo puedes resolver esta situación? Es fácil, todo lo que tienes que hacer es basar tu trabajo en la versión más reciente de la rama remota.", + "", + "Hay un par de maneras de hacer esto, pero la más simple es mover tu trabajo haciendo un rebase. Probémoslo a ver cómo se ve." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Ahora, si hacemos rebase antes de hacer push..." + ], + "afterMarkdowns": [ + "¡Zas! Actualizamos nuestra representación local del remoto con `git fetch`, hacemos rebase de nuestro trabajo para reflejar los nuevos cambios del remoto, y después los subimos con `git push`." + ], + "command": "git fetch; git rebase o/main; git push", + "beforeCommand": "git clone; git fakeTeamwork; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "¿Hay otra manera de actualizar mi trabajo si actualizaron el repositorio remoto? ¡Claro que sí! Veamos cómo hacer lo mismo pero usando `merge`.", + "", + "Por más que `git merge` no mueva tu trabajo (sólo crea un commit de merge), es un modo de decirle a git que integraste todos los cambios del remoto. Esto es porque ahora una rama remota pasó a ser un *ancestro* de tu propia rama, lo que significa que tu commit refleja los cambios de todos los commits de la rama remota.", + "", + "Veamos una muestra..." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Si en lugar de hacer rebase hacemos un merge..." + ], + "afterMarkdowns": [ + "¡Zas! Actualizamos nuestra representación local del remoto usando `git fetch`, *mergeamos* el nuevo trabajo junto con el nuestro (para reflejar los nuevos cambios en el remoto), y después los subimos usando `git push`." + ], + "command": "git fetch; git merge o/main; git push", + "beforeCommand": "git clone; git fakeTeamwork; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "¡Asombroso! ¿Hay forma de hacer esto sin escribir tantos comandos?", + "", + "¡Claro que sí! Ya sabes que `git pull` es simplemente un atajo para hacer fetch y merge. Convenientemente, ¡`git pull --rebase` es un atajo para hacer fetch y rebase!", + "", + "Veamos estos atajos funcionando." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Primero con `--rebase`..." + ], + "afterMarkdowns": [ + "¡Igual que antes! Sólo que bastante más corto." + ], + "command": "git pull --rebase; git push", + "beforeCommand": "git clone; git fakeTeamwork; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Y ahora un `pull` común" + ], + "afterMarkdowns": [ + "Otra vez, ¡exactamente lo mismo que antes!" + ], + "command": "git pull; git push", + "beforeCommand": "git clone; git fakeTeamwork; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Toda este tinglado de hacer fetch, rebase/merge y push es bastante común. En lecciones futuras vamos a ver formas más complejas de estos flujos de trabajo, pero por ahora vamos a probar esto que acabamos de ver.", + "", + "Para resolver este nivel, haz lo siguiente:", + "", + "* Clona tu repositorio", + "* Simula algo de trabajo de un colega (1 commit)", + "* Haz commit de algún cambio tuyo (1 commit)", + "* Publica tu trabajo *rebaseando*" + ] + } + } + ] + }, "pt_BR": { "childViews": [ { @@ -489,10 +640,10 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Chega de conversa! Vejamos essa situação na prática" + "Chega de conversa! Vejamos essa situação na prática." ], "afterMarkdowns": [ - "Viu? Nada aconteceu porque o comando falhou. O `git push` falha porque o commit mais recente (`C3`) é baseado no remoto em `C1`. Como o remoto foi atualizado no meio tempo, o Git rejeita o push" + "Viu? Nada aconteceu porque o comando falhou. O `git push` falha porque o commit mais recente (`C3`) é baseado no remoto em `C1`. Como o remoto foi atualizado no meio tempo, o Git rejeita o push." ], "command": "git push", "beforeCommand": "git clone; git fakeTeamwork; git commit" @@ -515,9 +666,9 @@ exports.level = { "Agora se nós fizermos um rebase antes do push..." ], "afterMarkdowns": [ - "Boom! Nós atualizamos a representação local do repositório remoto com `git fetch`, fizemos rebase do nosso trabalho para refletir as novas mudanças no repositório remoto, e então enviamos nossas mudanças com `git push`" + "Boom! Nós atualizamos a representação local do repositório remoto com `git fetch`, fizemos rebase do nosso trabalho para refletir as novas mudanças no repositório remoto, e então enviamos nossas mudanças com `git push`." ], - "command": "git fetch; git rebase o/master; git push", + "command": "git fetch; git rebase o/main; git push", "beforeCommand": "git clone; git fakeTeamwork; git commit" } }, @@ -540,9 +691,9 @@ exports.level = { "Agora se fizermos merge em vez de rebase ..." ], "afterMarkdowns": [ - "Boom! Atualizamos nossa representação local do repositório remoto com `git fetch`, fizemos *merge* do novo trabalho com o nosso (para refletir as novas mudanças no repositório remoto), e então fizemos push deles com `git push`" + "Boom! Atualizamos nossa representação local do repositório remoto com `git fetch`, fizemos *merge* do novo trabalho com o nosso (para refletir as novas mudanças no repositório remoto), e então fizemos push deles com `git push`." ], - "command": "git fetch; git merge o/master; git push", + "command": "git fetch; git merge o/main; git push", "beforeCommand": "git clone; git fakeTeamwork; git commit" } }, @@ -575,7 +726,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "E agora com o `pull` normal" + "E agora com o `pull` normal." ], "afterMarkdowns": [ "De novo, exatamente como antes!" @@ -601,6 +752,150 @@ exports.level = { } ] }, + + "gl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Traballo diverxente", + "", + "Ata agora vimos cómo descargar e mesturar os commits de outros e como empurrar os nosos. Parece bastante sinxelo, así que ¿cómo pode confundirse tanto a xente?", + "", + "A dificultade ven cando a historia dos repositorios *diverxe*. Antes de entrar nos detalles, vexamos un examplo...", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Imaxínate que clonas un repositorio o luns e comezas a desenvolver algo. Para o venres, xa estás listo para publicar o teu traballo, pero, ¡oh, oh! Os teus colegas tamén fixeron código durante a semana, facendo que o teu traballo quede desactualizado (e obsoleto). Ademáis, eles publicaron eses commits no repositorio remoto, así que agora o *teu* traballo está baseado nunha versión *vella* do proxecto, que xa non lle interesa a ninguén.", + "", + "Neste caso, o comando `git push` é ambiguo. Se executas `git push`, ¿git debería mudar o repositorio para como estaba o luns? ¿Deberías arranxar o teu código sen eliminar o código novo? ¿Ou debería ignorar completamente os teus cambio porque xa están desactualizados?", + "", + "Como hai tanta ambiguedade nesta situación (na que a historia diverxeu), git non che permite empurrar os teus cambios. En cambio, fórzate a integrar o último estado do respositorio remoto antes de poder compartir o teu traballo." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "¡Demasiada charla, vexámolo en acción!" + ], + "afterMarkdowns": [ + "¿Ves? Non pasou nada, porque o comando falla. `git push` falla porque `C3`, o teu commit máis recente, está baseado no remoto sobre `C1`. O remoto foi actualizado a `C2` dende entonces, polo que git rechaza o teu push." + ], + "command": "git push", + "beforeCommand": "git clone; git fakeTeamwork; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "¿Cómo resolves esta situación? É sinxelo, todo o que tes que facer é basear o teu traballo na versión máis recente da rama remota.", + "", + "Hai un par de formas de facer esto, pero a máis sinxela é mover o teu traballo facendo un rebase. Probémolo a ver cómo se ve." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Agora, se facemos rebase antes de empurrar..." + ], + "afterMarkdowns": [ + "¡Boom! Actualizamos a nosa representación local do remoto con `git fetch`, rebasamos o noso traballo para reflexar os novos cambios do remoto, e despois os empurramos con `git push`." + ], + "command": "git fetch; git rebase o/main; git push", + "beforeCommand": "git clone; git fakeTeamwork; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "¿Hai outra forma de actualizar o meu traballo se actualizaran o repositorio remoto? ¡Pois claro! Vexamos cómo facer o mesmo pero empregando `merge`.", + "", + "Por máis que `git merge` non mova o teu traballo (só crea un commit de merge), é un modo de decirlle a git que integrase tódolos cambios do remoto. Esto é porque agora unha rama remota pasou a ser un *ancestro* da tua propia rama, o que significa que o teu commit reflexa os cambios de tódolos commits da rama remota.", + "", + "Vexamos unha mostra..." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Si no lugar de rebasar facemos un merge..." + ], + "afterMarkdowns": [ + "¡Boom! Actualizamos a nosa representación local do remoto usando `git fetch`, *mesturamos* ou *mergeamos* o novo traballo xunto co noso (para reflexar os novos cambios no remoto), e despois os empurramos empregando `git push`." + ], + "command": "git fetch; git merge o/main; git push", + "beforeCommand": "git clone; git fakeTeamwork; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "¡Asombroso! ¿Hai forma de facer esto sen escreber tantos comandos?", + "", + "¡Claro que sí! Xa sabes que `git pull` é sinxelamente un atallo para facer fetch e merge. Ademáis, ¡`git pull --rebase` é un atallo para facer fetch e rebase!", + "", + "Vexamos estos atallos funcionando." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Primeiro con `--rebase`..." + ], + "afterMarkdowns": [ + "¡Igual que antes! Só que máis corto." + ], + "command": "git pull --rebase; git push", + "beforeCommand": "git clone; git fakeTeamwork; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "E agora un `pull` común" + ], + "afterMarkdowns": [ + "Outra vez, ¡exactamente o mesmo que antes!" + ], + "command": "git pull; git push", + "beforeCommand": "git clone; git fakeTeamwork; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Toda esta movida de fetchear, rebasear/mergear e pushear é bastante común. Nas seguintes leccións imos ver formas máis complexas de estes fluxos de traballo, pero por agora probemos o que vimos.", + "", + "Para resolver este nivel, fai o siguiente:", + "", + "* Clona o teu repositorio", + "* Simula algo de trabajo dun colega (1 commit)", + "* Commitea algo de traballo propio (1 commit)", + "* Publica o teu traballo *rebasando*" + ] + } + } + ] + }, "zh_TW": { "childViews": [ { @@ -660,7 +955,7 @@ exports.level = { "afterMarkdowns": [ "看吧!我們利用 `git fetch` 下載了 remote 上面的 commit,並且 rebase 我們的 commit,使得我們的 commit 可以接在 remote 上面最新的版本的後面,接著透過 `git push` 就可以上傳更新了。" ], - "command": "git fetch; git rebase o/master; git push", + "command": "git fetch; git rebase o/main; git push", "beforeCommand": "git clone; git fakeTeamwork; git commit" } }, @@ -685,7 +980,7 @@ exports.level = { "afterMarkdowns": [ "看吧!我們藉由 `git fetch` 把 remote 上的 commit 下載下來,並且 *merged* 該 commit 到我們目前的 branch(這樣就表示我們產生的 merge commit 有包含了 remote 上的 commit),接著再透過 `git push` 上傳到 remote。" ], - "command": "git fetch; git merge o/master; git push", + "command": "git fetch; git merge o/main; git push", "beforeCommand": "git clone; git fakeTeamwork; git commit" } }, @@ -765,7 +1060,7 @@ exports.level = { "markdowns": [ "假设你周一克隆了一个仓库,然后开始研发某个新功能。到周五时,你新功能开发测试完毕,可以发布了。但是 —— 天啊!你的同事这周写了一堆代码,还改了许多你的功能中使用的 API,这些变动会导致你新开发的功能变得不可用。但是他们已经将那些提交推送到远程仓库了,因此你的工作就变成了基于项目**旧版**的代码,与远程仓库最新的代码不匹配了。", "", - "这种情况下, `git push` 就不知道该如何操作了。如果你执行 `git push`,Git 应该让远程仓库回到星期一那天的状态吗?还是直接在新代码的基础上添加你的代码,异或由于你的提交已经过时而直接忽略你的提交?", + "这种情况下, `git push` 就不知道该如何操作了。如果你执行 `git push`,Git 应该让远程仓库回到星期一那天的状态吗?还是直接在新代码的基础上添加你的代码,亦或由于你的提交已经过时而直接忽略你的提交?", "", "因为这情况(历史偏离)有许多的不确定性,Git 是不会允许你 `push` 变更的。实际上它会强制你先合并远程最新的代码,然后才能分享你的工作。" ] @@ -801,9 +1096,9 @@ exports.level = { "如果我们在 push 之前做 rebase 呢?" ], "afterMarkdowns": [ - "我们用 `git fetch` 更新了本地仓库中的远程分支,然后用 rebase 将工们的工作移动到最新的提交记录下,最后再用 `git push` 推送到远程仓库。" + "我们用 `git fetch` 更新了本地仓库中的远程分支,然后用 rebase 将我们的工作移动到最新的提交记录下,最后再用 `git push` 推送到远程仓库。" ], - "command": "git fetch; git rebase o/master; git push", + "command": "git fetch; git rebase o/main; git push", "beforeCommand": "git clone; git fakeTeamwork; git commit" } }, @@ -828,7 +1123,7 @@ exports.level = { "afterMarkdowns": [ "我们用 `git fetch` 更新了本地仓库中的远程分支,然后**合并**了新变更到我们的本地分支(为了包含远程仓库的变更),最后我们用 `git push` 把工作推送到远程仓库" ], - "command": "git fetch; git merge o/master; git push", + "command": "git fetch; git merge o/main; git push", "beforeCommand": "git clone; git fakeTeamwork; git commit" } }, @@ -910,7 +1205,7 @@ exports.level = { "", "In diesem Fall ist ein `git push` problematisch. Wenn du es ausführst, soll Git das entfernte Repository in den Zustand von Montag zurückversetzen? Soll es versuchen deinen Code auf die aktuelle Version zu packen? Oder soll es deine Änderungen einfach ignorieren, weil sie total veraltet sind?", "", - "Da es in dieser Situation so viele Mehrdeutigkeiten gibt (da die Historys divergent sind) erlaubt Git dir nicht, deine Änderungen einfach zu `push`en. Es zwingt dich, zuerst die neuesten Änderungen vom Server zu holen und in deine zu integrieren bevor du deine Arbeit mit anderen teilen kannst." + "Da es in dieser Situation so viele Mehrdeutigkeiten gibt (da die Historys divergieren), erlaubt Git dir nicht, deine Änderungen einfach zu `push`en. Es zwingt dich, zuerst die neuesten Änderungen vom Server zu holen und in deine zu integrieren, bevor du deine Arbeit mit anderen teilen kannst." ] } }, @@ -933,7 +1228,7 @@ exports.level = { "markdowns": [ "Wie sollen wir das auflösen? Es ist ganz einfach, du musst deinen Commit nur von der aktuellsten Version des Remotes ableiten.", "", - "Es gibt verschiedene Möglichkeiten wie man das erreichen kann, aber die offensichtlichste ist es, deine Commits per Rebase zu verschieben. Schauen wir mal wie das abläuft:" + "Es gibt verschiedene Möglichkeiten, wie man das erreichen kann, aber die offensichtlichste ist, deine Commits per Rebase zu verschieben. Schauen wir mal wie das abläuft:" ] } }, @@ -946,7 +1241,7 @@ exports.level = { "afterMarkdowns": [ "Bämm! Wir haben unsere lokale Abbildung des entfernten Repositorys mit `git fetch` auf den neuesten Stand gebracht, unsere Arbeit auf die neueste Version des Remotes drauf gepackt und dann mit `git push` auf den Server geschoben." ], - "command": "git fetch; git rebase o/master; git push", + "command": "git fetch; git rebase o/main; git push", "beforeCommand": "git clone; git fakeTeamwork; git commit" } }, @@ -954,9 +1249,9 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Gibt es noch weitere Möglichkeiten deine Arbeit zu aktualisieren wenn das entfernte Repository neue Commits bekommen hat? Klar! Schauen wir uns dasselbe an, aber diesmal arbeiten wir mit `merge`.", + "Gibt es noch weitere Möglichkeiten deine Arbeit zu aktualisieren, wenn das entfernte Repository neue Commits bekommen hat? Klar! Schauen wir uns dasselbe an, aber diesmal arbeiten wir mit `merge`.", "", - "Obwohl `git merge` deine Arbeit nicht verschiebt (und stattdessen einen Merge Commit erzeugt) ist es eine Möglichkeit Git dazu zu bringen, alle Änderungen vom Remote in deine Sachen zu integrieren. Denn durch den Merge wird der Remote Branch zu einem *Vorgänger* deines Branches, was bedeutet dass dein Commit alle Commits des entfernten Branches beinhaltet.", + "Obwohl `git merge` deine Arbeit nicht verschiebt (und stattdessen einen Merge Commit erzeugt) ist es eine Möglichkeit Git dazu zu bringen, alle Änderungen vom Remote in deine Sachen zu integrieren. Denn durch den Merge wird der Remote Branch zu einem *Vorgänger* deines Branches, was bedeutet, dass dein Commit alle Commits des entfernten Branches beinhaltet.", "", "Zur Demonstration ..." ] @@ -971,7 +1266,7 @@ exports.level = { "afterMarkdowns": [ "Ok. Wir haben die lokale Abbildung des entfernen Repositorys mit `git fetch` aktualisiert, die neuen Änderungen per *Merge* in deine integriert, und letztere dann mit `git push` auf den Server gebracht." ], - "command": "git fetch; git merge o/master; git push", + "command": "git fetch; git merge o/main; git push", "beforeCommand": "git clone; git fakeTeamwork; git commit" } }, @@ -1024,7 +1319,7 @@ exports.level = { "* Clone dein Repository", "* Simuliere einen entfernten Commit mit `git fakeTeamwork`", "* Erzeuge einen lokalen Commit", - "* Benutze *Rebase*, um deine Arbeit schließlich pushen zu können" + "* Benutze *Rebase*, um deine Arbeit schließlich pushen zu können." ] } } @@ -1087,9 +1382,9 @@ exports.level = { "Теперь, когда мы сперва перебазируемся прежде чем публиковать изменения..." ], "afterMarkdowns": [ - "Опа! Мы только что обновили наш локальный образ удалённого репозитория средствами `git fetch`. Ещё мы перебазировали наши наработки, чтобы они отражали все изменения с удалённого репозитория, и опубликовали их с помощью `git push`" + "Опа! Мы только что обновили наш локальный образ удалённого репозитория средствами `git fetch`. Ещё мы перебазировали наши наработки, чтобы они отражали все изменения с удалённого репозитория, и опубликовали их с помощью `git push`." ], - "command": "git fetch; git rebase o/master; git push", + "command": "git fetch; git rebase o/main; git push", "beforeCommand": "git clone; git fakeTeamwork; git commit" } }, @@ -1112,9 +1407,9 @@ exports.level = { "Таким образом, если мы объединим (merge) вместо перебазирования (rebase)..." ], "afterMarkdowns": [ - "Опа! Мы обновили наше локальное представление удалённого репозитория с помощью `git fetch`, *объединили* ваши новые наработки с нашими наработками (чтобы отразить изменения в удалённом репозитории) и затем опубликовали их с помощью `git push`" + "Опа! Мы обновили наше локальное представление удалённого репозитория с помощью `git fetch`, *объединили* ваши новые наработки с нашими наработками (чтобы отразить изменения в удалённом репозитории) и затем опубликовали их с помощью `git push`." ], - "command": "git fetch; git merge o/master; git push", + "command": "git fetch; git merge o/main; git push", "beforeCommand": "git clone; git fakeTeamwork; git commit" } }, @@ -1147,7 +1442,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "А теперь с обычным `pull`" + "А теперь с обычным `pull`." ], "afterMarkdowns": [ "И снова - результат такой же, как и ранее!" @@ -1232,7 +1527,7 @@ exports.level = { "afterMarkdowns": [ "わお!私たちは`git fetch`でローカルのリモートブランチを更新し、私たちの作業をリベースさせてリモートの新しい変更に適用させ、`git push`でそれをプッシュしました。" ], - "command": "git fetch; git rebase o/master; git push", + "command": "git fetch; git rebase o/main; git push", "beforeCommand": "git clone; git fakeTeamwork; git commit" } }, @@ -1257,7 +1552,7 @@ exports.level = { "afterMarkdowns": [ "わお!私たちは`git fetch`でローカルのリモートブランチを更新し、私たちの作業を*マージ*して(リモートの新しい変更を反映するために)、`git push`でそれをプッシュしました。" ], - "command": "git fetch; git merge o/master; git push", + "command": "git fetch; git merge o/main; git push", "beforeCommand": "git clone; git fakeTeamwork; git commit" } }, @@ -1375,7 +1670,7 @@ exports.level = { "afterMarkdowns": [ "Ка-бум! Ми оновили наш локальний образ віддаленого репозиторію за допомогою `git fetch`, заребейсили наші напрацювання відповідно до змін у віддаленому репо, й завантажили їх за допомогою `git push`." ], - "command": "git fetch; git rebase o/master; git push", + "command": "git fetch; git rebase o/main; git push", "beforeCommand": "git clone; git fakeTeamwork; git commit" } }, @@ -1398,9 +1693,9 @@ exports.level = { "Тепер ми зробимо merge замість rebase..." ], "afterMarkdowns": [ - "Ка-бум! Ми оновили наш локальний образ віддаленої гілки за допомогою `git fetch`, *змерджили* нові напрацювання з власними (щоб відобразити останні зміни у віддаленій гілці), й відіслали їх за допомогою `git push`" + "Ка-бум! Ми оновили наш локальний образ віддаленої гілки за допомогою `git fetch`, *змерджили* нові напрацювання з власними (щоб відобразити останні зміни у віддаленій гілці), й відіслали їх за допомогою `git push`." ], - "command": "git fetch; git merge o/master; git push", + "command": "git fetch; git merge o/main; git push", "beforeCommand": "git clone; git fakeTeamwork; git commit" } }, @@ -1433,7 +1728,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "А тепер просто з `pull`" + "А тепер просто з `pull`." ], "afterMarkdowns": [ "Знову, так як і було!" @@ -1518,7 +1813,7 @@ exports.level = { "afterMarkdowns": [ "Boom! `git fetch`로 원격 저장소의 변경정보를 가져오고, 새 변경들로 우리 작업을 리베이스 했습니다, 이제 `git push`하면 끝!" ], - "command": "git fetch; git rebase o/master; git push", + "command": "git fetch; git rebase o/main; git push", "beforeCommand": "git clone; git fakeTeamwork; git commit" } }, @@ -1543,7 +1838,7 @@ exports.level = { "afterMarkdowns": [ "Boom! `git fetch`로 원격 저장소의 변경정보를 가져오고, 새 작업을 우리 작업으로 *병합*했습니다 (원격 저장소의 변경을 반영하기 위해서죠), 이제 `git push`하면 끝!" ], - "command": "git fetch; git merge o/master; git push", + "command": "git fetch; git merge o/main; git push", "beforeCommand": "git clone; git fakeTeamwork; git commit" } }, @@ -1601,6 +1896,292 @@ exports.level = { } } ] + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Diverged Work", + "", + "Cho đến giờ ta đã biết cách `kéo`(`pull`) commit từ nơi khác về và cách `đẩy`(`push`) lên những thay đổi của ta. Chúng nhìn có vẻ khá đơn giản, vậy tại sao người ta lại thấy lúng túng về chúng?", + "", + "Khó khăn đến từ sự *dị biệt* của cây lịch sử trên kho chứa từ xa. Trước khi đi vào thảo luận chi tiết vấn đề này, hãy xem qua một ví dụ...", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Tưởng tượng bạn sao chép một kho chứa vào thứ Hai và bắt đầu phát triển một tính năng mới. Đến thứ Sáu thì bạn đã sẵn sàng để xuất bản thành quả của mình -- nhưng không! Đồng nghiệp của bạn đã viết thêm hàng loạt mã trong một tuần vừa rồi và điều này làm cho chức năng của bạn trở nên lỗi thời. Và họ cũng đã xuất bản những commit này lên kho chứa từ xa chung, vậy giờ thành quả của *bạn* lại dựa trên phiên bản *cũ* của dự án mà nó không còn thích đáng nữa.", + "", + "Trong trường hợp này, lệnh `git push` trở lên khá nhập nhằng. Nếu bạn dùng `git push`, liệu git nên thay đổi kho chứa từ xa trơ rveef trạng thái ngày thứ Hai? Hay nó nên cố gắng thêm mã của bạn vào trong khi không xóa mã mới? Hay là nó sẽ bỏ qua hoàn toàn mã của bạn vì nó đã lỗi thời?", + "", + "Vì có quá nhiều tình huống mơ hồ (dị biệt lịch sử), git sẽ không cho phép bạn `đẩy`(`push`) thay đổi của mình. Nó sẽ ép bạn phải sát nhập trạng thái mới nhất của kho chứa từ xa vào thành phẩm của mình trước khi chia sẻ chúng." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Nói quá nhiều rồi! Đi vào hành động thôi" + ], + "afterMarkdowns": [ + "Thấy chứ? Không có gì xảy ra cả vì lệnh bị thất bại. `git push` thất bại vì commit mới nhất của bạn: `C3` dựa trên commit `C1` ở nhánh từ xa. Nhánh đó đã được cập nhật lên commit `C2`, nên git từ chối lệnh đẩy của bạn" + ], + "command": "git push", + "beforeCommand": "git clone; git fakeTeamwork; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Vậy thì giải quyết tình huống này sao giờ? Đơn giản thôi, tất cả những gì bạn cần làm là khiến cho thành quả của mình dựa trên phiên bản mới nhất của nhánh từ xa.", + "", + "Có vài cách để làm điều này, nhưng cách trực tiếp nhất là bố trí lại (dùng rebase) để di chuyển thành quả của bạn. Cùng xem cách nó hoạt động nào." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Nào bây giờ trước push ta dùng rebase thì..." + ], + "afterMarkdowns": [ + "Bùùm! Ta đã cập nhật nhánh từ xa trong kho chứ cục bộ với `git fetch`, dịch chuyển thành quả của mình để phản ánh thay đổi mới của kho chứa từ xa, sau đó đẩy chúng lên với `git push`." + ], + "command": "git fetch; git rebase o/main; git push", + "beforeCommand": "git clone; git fakeTeamwork; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Có cách nào khác để cập nhật thành quả của mình khi kho chứa từ xa được cập nhật không? Tất nhiên rồi! Hãy xem xét điều tương tự với `merge`.", + "", + "Mặc dù `git merge` không dịch chuyển commit của bạn (thay vì đó nó tạo ra một commit hơp nhất), đó là cách để nói với git rằng bạn đã kết hợp tất cả thay đổi từ nhánh từ xa. Đó là bởi vì bây giờ nhánh từ xa đã trở thành một *tổ tiên* của nhánh cục bộ của bạn, nghĩa là commit của bạn có thể tham chiếu điến tất cả commit có ở nhánh tù xa.", + "", + "Hãy xem qua bản biểu diễn sau..." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Giờ nếu ta dùng merge thay vày rebase thì..." + ], + "afterMarkdowns": [ + "Bùùm! Ta đã cập nhật đại diện nhánh từ xa tại kho chứa địa phương với `git fetch`, *hợp nhất* (*merge*) thành quả mới vào thành quả của ta (để phản ánh thay đổi ở nhánh từ xa), sau đó đẩy chúng lên với `git push`." + ], + "command": "git fetch; git merge o/main; git push", + "beforeCommand": "git clone; git fakeTeamwork; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Tuyệt vời! Có cách nào để làm việc này mà không phải gõ nhiều lệnh thế không nhỉ?", + "", + "Tất nhiên rồi -- bạn đã biết rằng `git pull` là lệnh tắt của fetch và merge. Tương tự như vậy, `git pull --rebase` là lệnh tắt của fetch và rebase!", + "", + "Hãy xem thử cách lệnh tắt này hoạt động ra sao." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Trước tiên với `--rebase`..." + ], + "afterMarkdowns": [ + "Giống hệt như trước! Chỉ là lệnh ngắn hơn." + ], + "command": "git pull --rebase; git push", + "beforeCommand": "git clone; git fakeTeamwork; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Và giờ với lệnh `pull` thông thường." + ], + "afterMarkdowns": [ + "Lại một lần nữa, chính xác y hệt như trước!" + ], + "command": "git pull; git push", + "beforeCommand": "git clone; git fakeTeamwork; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Quy trình tìm nạp (fetch), bố trí lại/hợp nhất (rebase/merge), và đẩy (push) là khá phổ biết. Ta sẽ xem xét các phiên bản phức tạp hơn của những quy trình này ở các bài học sau, còn bây giờ thì hãy tập trung vào bài này đã.", + "", + "Để giải quyết cấp độ này, hãy làm các bước sau:", + "", + "* Nhân bản kho chứa của bạn", + "* Giả lập làm việc nhóm (1 commit)", + "* Tạo ra 1 commit địa phương", + "* Xuất bản thành quả của bạn dùng *rebase*" + ] + } + } + ] + }, + "sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Razdeljeno Delo", + "", + "Zaenkrat smo videli kako `pullat` dol commite od ostalih in kako `pushat` naše spremembe. Izgleda dokaj preprosto, vendar kako lahko vseeno to mede ljudi?", + "", + "Težave nastopijo, ko se zgodovina repozitorijev *razdeli*. Preden se lotimo podrobnosti si poglejmo primer ...", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Predstavljaj si, da skloniraš repozitorij v ponedeljek in začneš delati na novi funkcionalnosti. V petek si pripravljen, da objaviš svoje spremembe -- ampak o ne! Tvoji sodelavci so napisali goro kode med tednom in tvoja funkcionalnost je postala zastarela. Prav tako so objavili te commite v skupen repozitorij, tako da sedaj *tvoje* delo izhaja iz *stare* verzije projekta, ki ni več taprava.", + "", + "V tem primeru je ukaz `git push` dvoumen. Če bi pognal `git push`, bi git moral spremeniti oddaljeni repozitorij nazaj na stanje iz ponedeljka? Bi moral poizkusiti dodati tvoje delo, brez da odstarani novo kodo? Ali bi moral povsem ignorirati tvoje spremembe, ker so zastarele?", + "", + "Ker je toliko dvomov v tej situaciji (kjer se je zgodovina razdelila), ti git ne pusti, da bi `pushal` svoje spremembe. V bistvu te prisili, da vključiš zadnje stanje oddaljenega repozitorija, preden lahko deliš svoje delo." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Toliko govorjenja! Poglejmo stvar v praksi." + ], + "afterMarkdowns": [ + "Vidiš? Nič se ni spremenilo, ker je ukaz spodeletel. `git push` spodleti, ker tvoj zadnji commit `C3` izhaja iz oddaljenega `C1`. Oddaljen repozitorij se je med tem posodobil na `C2`, zato git zavrne tvoj push." + ], + "command": "git push", + "beforeCommand": "git clone; git fakeTeamwork; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Kako rešiti to zagato? Enostavno je, vse kar moraš narediti je, da spremeniš, da tvoje delo izhaja iz zadnje verzije oddaljenega brancha.", + "", + "Obstaja nekaj načinov, da to narediš, ampak najnaravnejši način je, da to narediš z rebaseom. Poglejmo, kako to izgleda." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Če sedaj rebaseamo, namesto da pushamo ..." + ], + "afterMarkdowns": [ + "Boom! Posodobili smo našo lokalno reprezentacijo oddaljenega repozitorija z `git fetch`, rebaseali naše delo, da vsebuje nove spremembe iz oddaljenega repota, nato pa naložili svoje delo z `git push`." + ], + "command": "git fetch; git rebase o/main; git push", + "beforeCommand": "git clone; git fakeTeamwork; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "So še drugi načini, da posodobim svoj delo, ko je bil oddaljen repozitorij posodobljen? Seveda! Poglejmo isto stvar, vendar tokrat z `mergeom`.", + "", + "Čeprav `git merge` ne premakne tvojega dela (ampak naredi samo merge commit), je to način da sporočiš gitu, da si vključil vse spremembe iz oddaljenega repota. To je zato, ker je oddaljen branch sedaj *prednik* tvojega brancha, kar pomeni, da tvoj commit sedaj vsebuje vse commite iz oddaljenega brancha.", + "", + "Poglejmo predstavitev tega ..." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Če sedaj uporabimo merge namesto rebasea ..." + ], + "afterMarkdowns": [ + "Boom! Posodobili smo našo lokalno sliko oddaljenega repozitorija z `git fetch`, *zmergali* novo delo v naše delo (kot odraz novih sprememb na oddaljenem branchu) in jih nato naložili z `git push`." + ], + "command": "git fetch; git merge o/main; git push", + "beforeCommand": "git clone; git fakeTeamwork; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Super! A obstaja način, da naredim vse to brez tipkanja toliko ukazov?", + "", + "Seveda -- `git pull` že poznaš in je bližnjica za fetch ter merge. Prikladno je tudi `git pull --rebase` bližnjica za fetch in rebase!", + "", + "Poglejmo te kratke ukaze na delu." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Najprej z `--rebase` ..." + ], + "afterMarkdowns": [ + "Enako kot prej! Le dosti krajše." + ], + "command": "git pull --rebase; git push", + "beforeCommand": "git clone; git fakeTeamwork; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "In sedaj z navadnim `pullom` ..." + ], + "afterMarkdowns": [ + "Zopet enako kot prej!" + ], + "command": "git pull; git push", + "beforeCommand": "git clone; git fakeTeamwork; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Vse to fetchanje, rebasanje/merganje in pushanje je kar pogosto. V prihodnjih lekcijah bomo preučili težje različice teh postopkov, ampak najprej preizkusimo tega.", + "", + "Da rešiš to stopnjo, izvedi sledeče korake:", + "", + "* Kloniraj svoj repozitorij", + "* Naredi lažni commit ostale ekipe (1 commit)", + "* Commitaj nekaj svojega dela (1 commit)", + "* Objavi svoje delo z *rebaseom*" + ] + } + } + ] } } }; diff --git a/src/levels/remote/lockedMaster.js b/src/levels/remote/lockedMaster.js new file mode 100644 index 00000000..14506f27 --- /dev/null +++ b/src/levels/remote/lockedMaster.js @@ -0,0 +1,526 @@ +exports.level = { + "goalTreeString": "{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\"},\"o/master\":{\"target\":\"C1\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null},\"feature\":{\"target\":\"C2\",\"id\":\"feature\",\"remoteTrackingBranchID\":\"o/feature\"},\"o/feature\":{\"target\":\"C2\",\"id\":\"o/feature\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"}},\"tags\":{},\"HEAD\":{\"target\":\"feature\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\",\"remoteTrackingBranchID\":null},\"feature\":{\"target\":\"C2\",\"id\":\"feature\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"}},\"tags\":{},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", + "solutionCommand": "git reset --hard o/main;git checkout -b feature C2; git push origin feature", + "startTree": "{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\"},\"o/master\":{\"target\":\"C1\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"}},\"tags\":{},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"}},\"tags\":{},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", + "hint": { + "en_US": "Make the feature branch from the local main before resetting it back to be the same as origin's main", + "de_DE": "Erstelle einen Feature-Branch ausgehend vom lokalen Master-Branch, bevor du den Master-Branch auf den origin/main zurücksetzt.", + "ru_RU": "Создайте новую feature ветвь от main перед тем, как откатить изменения в main до состояния o/main.", + "uk": "Створіть нову feature гілку від локального main перед тим, як відкотити зміни в main до стану o/main.", + "zh_CN": "从本地的master创建一个feature分支, 然后重置master和origin master保持一致。", + "es_ES": "Crea la rama feature desde la rama main en local antes de restablecerlo para que sea el mismo que la rama main de origen", + "pt_BR": "Crie o ramo feature a partir do ramo main no local antes de reestabelecê-lo para que seja o mesmo que o ramo main de origem", + "fr_FR": "Créer la branche feature à partir du main local, avant de la restaurer dans le même état que o/main", + "ko" : "로컬 저장소의 main 브랜치로부터 feature 브랜치를 만드세요. 그리고 o/main과 같아질 수 있도록 로컬 저장소의 main 브랜치를 reset 하세요.", + "sl_SI": "Naredi feature branch iz lokalnega masterja preden ga ponastaviš, da bo enak kot origin main.", + "es_AR": "Crea la rama feature desde la rama main en local antes de restablecerlo para que sea el mismo que la rama main de origen.", + "ja": "mainブランチをoriginのmainと同じ状態になるようにリセットする前に、ローカルのmainからfeatureブランチを作成します。" + }, + "name": { + "en_US": "Locked Master", + "de_DE": "Gesperrter Master-Branch", + "ru_RU": "Заблокированная ветвь main", + "uk": "Заблокована гілка main", + "zh_CN": "锁定的Master(Locked Master)", + "es_ES": "Master bloqueado", + "pt_BR": "Master bloqueado", + "fr_FR": "Master verrouillé", + "ko" : "잠겨버린 main 브랜치", + "sl_SI": "Zaklenjen Master", + "es_AR": "Master bloqueado", + "ja": "ロックされたmaster" + }, + "startDialog": { + "en_US": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Remote Rejected!", + "", + "If you work on a large collaborative team its likely that main is locked and requires some Pull Request process to merge changes. If you commit directly to main locally and try pushing you will be greeted with a message similar to this:", + "", + "```", + " ! [remote rejected] main -> main (TF402455: Pushes to this branch are not permitted; you must use a pull request to update this branch.)", + "```" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Why was it rejected?", + "", + "The remote rejected the push of commits directly to main because of the policy on main requiring pull requests to instead be used.", + "", + "You meant to follow the process creating a branch then pushing that branch and doing a pull request, but you forgot and committed directly to main. Now you are stuck and cannot push your changes." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## The solution", + "", + "Create another branch called feature and push that to the remote. Also reset your main back to be in sync with the remote otherwise you may have issues next time you do a pull and someone else's commit conflicts with yours." + ] + } + } + ] + }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Gesperrter Master-Branch", + "", + "Wenn du in einem großen Team zusammen arbeitest, ist der Master-Branch mit hoher Wahrscheinlichkeit für direkte Änderungen gesperrt. Um Änderungen am Remote-Branch einpflegen zu können, ist ein Pull-Request-Prozess notwendig. Wenn du lokal in deinem Master-Branch einen Commit durchführst und diesen versuchst auf den serverseitigen Master-Branch zu pushen, wirst du folgende Fehlermeldung bekommen:", + "", + "```", + " ! [remote rejected] main -> main (TF402455: Pushes to this branch are not permitted; you must use a pull request to update this branch.)", + "```" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Wieso wurde diese Aktion zurückgewiesen?", + "", + "Auf Grund der serverseitig voreingestellten Richtlinien sind direkte Änderungen am Master-Branch nicht erlaubt, und erfordert einen Pull-Request.", + "", + "Um die eigenen lokalen Änderungen in den Master-Branch einbringen zu können, ist es erforderlich einen lokalen Feature-Branch zu erstellen. Dieser Feature-Branch muss dann auf den Server hochgeladen werden, damit dann ein Pull-Request eingeleitet werden kann. Dies wurde vorher durch den direkten Push des Master-Branch nicht berücksichtigt, weswegen man die Änderungen nicht hochladen konnte." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Die Lösung", + "", + "Erstelle einen Branch der feature heißt und pushe diesen auf den Server. Setze den lokalen Master-Branch zurück, dass er mit dem Origin-Master-Branch synchron ist. Dies könnte sonst später zu Komplikationen führen, wenn weitere `pull`s durchgeführt und Commits von anderen mit deinen in Konflikt stehen." + ] + } + } + ] + }, + "zh_CN": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## 远程服务器拒绝!(Remote Rejected)", + "", + "如果你是在一个大的合作团队中工作, 很可能是master被锁定了, 需要一些Pull Request流程来合并修改。如果你直接提交(commit)到本地master, 然后试图推送(push)修改, 你将会收到这样类似的信息:", + "", + "```", + " ! [远程服务器拒绝] main -> main (TF402455: 不允许推送(push)这个分支; 你必须使用pull request来更新这个分支.)", + "```" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## 为什么会被拒绝?", + "", + "远程服务器拒绝直接推送(push)提交到master, 因为策略配置要求 pull requests 来提交更新.", + "", + "你应该按照流程,新建一个分支, 推送(push)这个分支并申请pull request,但是你忘记并直接提交给了master.现在你卡住并且无法推送你的更新." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## 解决办法", + "", + "新建一个分支feature, 推送到远程服务器. 然后reset你的master分支和远程服务器保持一致, 否则下次你pull并且他人的提交和你冲突的时候就会有问题." + ] + } + } + ] + }, + "ru_RU": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Remote Rejected!", + "", + "Когда вы работаете в составе большой команды разработчиков над проектом, то, вероятнее всего, ветвь `main` будет _заблокирована_. Для внесения изменений в неё в git существует понятие запроса на слияние `Pull Request`. В такой ситуации если вы закоммитите свои наработки непосредственно в `main` ветвь, а после выполните `git push`, то будет сгенерировано сообщение об ошибке:", + "", + "```", + " ! [remote rejected] main -> main (TF402455: Pushes to this branch are not permitted; you must use a pull request to update this branch.)", + "```", + "", + "```", + " ! [удалённо отклонено] main -> main (TF402455: Изменение этой ветви запрещены; вы можете использовать pull request для обновления этой ветви.)", + "```" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Почему произошло отклонение моих изменений?", + "", + "Удалённый репозиторий отклонил загруженные коммиты непосредственно в `main` ветку потому, что на `main` _настроена политика_, которая требует использование `Pull request` вместо обычного `git push`.", + "", + "Эта политика подразумевает процесс создания новой ветви разработки, внесение в неё всех необходимых коммитов, загрузка изменений в удалённый репозиторий и _открытие нового_ `Pull request`. Однако вы забыли про это и закоммитили наработки непосредственно в `main` ветвь. Теперь вы застряли и не можете запушить свои изменения :(. " + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Решение:", + "", + "Создайте ещё одну ветвь под названием `feature` и отправьте изменения на удалённый репозиторий. Также не забудьте вернуть вашу локальную `main` ветвь в исходное состояние (чтобы она была синхронизирована с удалённой). В противном случае у вас могут возникнуть проблемы при следующем выполнении `git pull`." + ] + } + } + ] + }, + "uk": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Remote Rejected!", + "", + "Коли ви працюєте над проектом в складі великої команди розробників, то, швидше за все, гілка `main` буде _заблокована_. Для внесення до неї змін в git існує поняття запиту на злиття `Pull Request`. В такій ситуації, якщо ви закомітите свої зміни безпосередньо в гілку `main`, а потім виконаєте `git push`, то буде згенероване повідомлення про помилку:", + "", + "```", + " ! [remote rejected] main -> main (TF402455: Pushes to this branch are not permitted; you must use a pull request to update this branch.)", + "```", + "", + "```", + " ! [віддалено відхилено] main -> main (TF402455: Зміни (push-запити) цієї гілки заборонені; ви повинні використовувати pull-запит для оновлення цієї гілки.)", + "```" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Чому мої зміни були відхилені?", + "", + "Віддалений репозиторій відхилив коміти завантажені безпосередньо в гілку `main` через те, що на `main` _налаштована політика_, яка вимагає використання `Pull request` замість звичайного `git push`.", + "", + "Ця політика має на увазі процес створення нової гілки розробки, внесення до неї всіх потрібних комітів, завантаження змін в віддалений репозиторій і _відкриття нового_ `Pull request`. Але ви про це забули (чи не знали) і закомітили свої доробки безпосередньо в гілку `main`. Тепер ви застрягли і не можене запушити свої зміни :(. " + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Рішення:", + "", + "Створіть ще одну гілку з назвою `feature` і відправте зміни у віддалений репозиторій. Також не забудьте повернути вашу локальну гілку `main` в вихідне положення (щоб вона була синхронізована з віддаленою). Інакше у вас можуть виникнути складнощі при наступному виконанні запиту `git pull`, коли коміти інших розробників конфліктуватимуть з вашими." + + ] + } + } + ] + }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Remote Rejected!", + "", + "Si trabajas en un equipo colaborativo, es probable que la rama `main` esté bloqueada y requiera algún proceso de `Pull Request` para poder `mergear` los cambios. Si haces `commit` directamente a `main` e intentas realizar `push`, recibirás un mensaje similar a este:", + "", + "```", + " ! [remote rejected] main -> main (TF402455: Pushes to this branch are not permitted; you must use a pull request to update this branch.)", + "```" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## ¿Por qué fue rechazado?", + "", + "Se rechazó el `push` del `commit` a la rama `main` debido a la política en la rama `main` que requiere el uso de `Pull Requests`.", + "", + "Trataste de crear una rama y luego hacer `pushs` creando un `Pull Request`, pero te olvidaste e hiciste `commit` directamente a `main`. Ahora estás atascado y no puedes hacer `push` de tus cambios." + + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## La solución", + "", + "Crea otra rama llamada `feature` y haz `push` a remoto. También restablece su rama `main` nuevamente para que esté sincronizado con el repositorio remoto; de lo contrario, puedes tener problemas la próxima vez que realices un `pull` y el `commit` de otra persona entre en conflicto con el tuyo." + ] + } + } + ] + }, + "pt_BR": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Remote Rejected!", + "", + "Se você trabalha em uma grande equipe colaborativa é provável que o main seja bloqueado e precise de alguns processos de Pull Request para unir mudanças. Se você commitar diretamente para o main localmente e tentar fazer um push você visualizará uma mensagem similar a essa:", + "", + "```", + " ! [remote rejected] main -> main (TF402455: Pushes to this branch are not permitted; you must use a pull request to update this branch.)", + "```" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Por que foi rejeitado?", + "", + "O repositório remoto rejeitou o push dos commits diretamente para o main por causa da política do main necessitando do uso dos pull requests.", + "", + "Você pretendia seguir o processo de criação de uma ramificação, fazendo um push dessa ramificação e fazendo um pull request, mas você esqueceu e commitou diretamente para o main. Agora você está preso e não consegue publicar suas mudanças." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## A solução", + "", + "Crie outro branch chamado feature e faça um push dele para o repositório remoto. Além disso, resete o main de volta a estar sincronizado com o repositório remoto para não ter problemas da próxima vez que fizer um pull e os commits de alguém mais conflitarem com o seu." + ] + } + } + ] + }, + "fr_FR": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Remote Rejected!", + "", + "Si vous travaillez dans une équipe de grande taille, il est probable que `main` soit verrouillée, et que le mécanisme de `Pull Request` soit nécessaire pour `merge` des changements. Si vous faites un `commit` directement sur le main local, et essayez de `push`, vous serez reçu avec un message de la sorte :", + "", + "```", + " ! [remote rejected] main -> main (TF402455: Pushes to this branch are not permitted; you must use a pull request to update this branch.)", + "```" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Pourquoi est-ce rejeté?", + "", + "Le dépôt distant a rejeté le `push` de `commit` directement sur `main`, à cause de la stratégie mise en place sur `main`, imposant plutôt l'usage des `pull requests`.", + "", + "Vous étiez censé suivre le processus suivant : créer une branche, `push`, et faire une `pull request`. Mais vous avez oublié et avez fait un `commit` directement sur `main`. Maintenant vous êtes coincé et ne pouvez pas faire un `push` de vos modifications." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## La solution", + "", + "Créer une autre branche appelée feature, et poussez la sur le serveur distant. Réinitialisez (`reset`) également votre `main` pour être en cohérence avec l'état du serveur distant, sinon vous pourriez avoir des problèmes la prochaine fois que vous faites un `pull`, et que quelqu'un d'autre `commit` des choses en conflit avec vos modifications." + ] + } + } + ] + }, + "ko": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## 원격저장소 거부! (Remote Rejected!)", + "", + "규모가 큰 개발팀에서 일하는 경우, 보통 원격저장소의 `main` 브랜치는 잠겨있습니다(locked). 그래서 변경사항을 적용하려면 pull request 과정을 거쳐야하죠. 만약에 여러분이 로컬 저장소의 `main`브랜치에서 커밋을 한 후 `push`하려고 시도한다면, 다음과 같은 오류를 받게 될겁니다. :", + "", + "```", + " ! [remote rejected] main -> main (TF402455: Pushes to this branch are not permitted; you must use a pull request to update this branch.)", + "```" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## 왜 거부됐나요?", + "", + "원격 저장소는 자신의 `main` 브랜치에 대한 직접적인 커밋을 제한합니다. 왜냐하면 `push` 대신에 pull request가 쓰여야 한다는 규칙이 원격 저장소의 `main` 브랜치에는 적용되어 있기 때문이죠.", + "", + "여러분은 브랜치를 따로 만들어 작업한 다음, 그것을 `push`하고 pull request를 하려 했습니다. 하지만 그걸 잊고 실수로 `main` 브랜치에서 직접 커밋을 해버렸네요! 이제 변경 사항을 `push` 하지도 못하고 옴짝달싹 못하는 상황이 되어버렸습니다." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## 해결책", + "", + "`feature` 라는 이름의 다른 브랜치를 만들어 원격 저장소에 `push` 하세요. 그리고 원격 저장소와 동기화될 수 있도록 로컬 저장소의 `main` 브랜치를 `reset`하세요. 그렇지 않으면 여러분이 다음에 `pull`을 시도할 때 문제가 발생하거나, 다른 협업자들의 커밋이 여러분의 커밋과 충돌할 수도 있습니다." + ] + } + } + ] + }, + "es_AR": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Remote Rejected!", + "", + "Si trabajas en un equipo colaborativo, es probable que la rama `main` esté bloqueada y requiera algún proceso de `Pull Request` para poder `mergear` los cambios. Si haces `commit` directamente a `main` e intentas realizar `push`, recibirás un mensaje similar a este:", + "", + "```", + " ! [remote rejected] main -> main (TF402455: Pushes to this branch are not permitted; you must use a pull request to update this branch.)", + "```" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## ¿Por qué fue rechazado?", + "", + "Se rechazó el `push` del `commit` a la rama `main` debido a la política en la rama `main` que requiere el uso de `Pull Requests`.", + "", + "Trataste de crear una rama y luego hacer `pushs` creando un `Pull Request`, pero te olvidaste e hiciste `commit` directamente a `main`. Ahora estás atascado y no puedes hacer `push` de tus cambios." + + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## La solución", + "", + "Crea otra rama llamada `feature` y haz `push` a remoto. También restablece su rama `main` nuevamente para que esté sincronizado con el repositorio remoto; de lo contrario, puedes tener problemas la próxima vez que realices un `pull` y el `commit` de otra persona entre en conflicto con el tuyo." + ] + } + } + ] + }, + "sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Oddaljena Zavrnitev!", + "", + "Če delaš v veliki ekipi je verjetno, da je main zaklenjen in zahteva Pull Request postopek za merganje sprememb. Če commitaš direktno na main lokalno, poizkusi pushati in dobil boš sporočilo podobno temu:", + "", + "```", + " ! [remote rejected] main -> main (TF402455: Pushes to this branch are not permitted; you must use a pull request to update this branch.)", + "```" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Zakaj je bil zavrnjen?", + "", + "Oddaljen repo je zavrnil pushanje commitov direktno na main zaradi politike, da se uporabljajo le pull requesti.", + "", + "Mišljeno je, da slediš temu procesu, da narediš branch, ga pushaš, nato pa narediš pull request, ampak si pozabil in commital direktno na main. Sedaj si zataknjen in ne moreš pushati svojih sprememb." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Rešitev", + "", + "Naredi še en branch imenovan feature in ga pushaj na remote. Prav tako resetiraj main nazaj, da bo v enakem stanju kot na oddaljenem repozitoriju, drugače imaš lahko težave naslednjič, ko boš pullal spremembe in bo konflikt s commitom nekoga drugega." + ] + } + } + ] + }, + "ja": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## リモートが拒否した!", + "", + "もしあなたが大規模な共同作業チームで働いている場合、mainがロックされていて、変更をマージするために何らかのプルリクエストの処理が必要になるかもしれません。ローカルで直接mainにコミットしてプッシュしようとすると、以下のようなメッセージに遭遇するでしょう:", + "", + "```", + " ! [remote rejected] main -> main (TF402455: Pushes to this branch are not permitted; you must use a pull request to update this branch.)", + "```" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## なぜ拒否されたのか?", + "", + "mainに対しては直接でのコミットの代わりにプルリクエストを要求するポリシーによって、リモートはmainに直接コミットしようとするプッシュを拒否しました。", + "", + "あなたはブランチを作成し、そのブランチをプッシュしてプルリクエストを行うという手順を踏むつもりでしたが、それを忘れてしまい直接mainにコミットしてしまったのです。あなたは行き詰まってしまい、変更をプッシュすることが出来なくなってしまいました。" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## 解決策", + "", + "featureという名前の別のブランチを作成し、リモートにプッシュしてください。またmainをresetしてリモートと同じ状態になるようにしてください。そうしないとあなたが次にプルを実行したときに問題が発生し、他の誰かのコミットがあなたのコミットと競合する恐れがあります。" + ] + } + } + ] + }, + } +}; diff --git a/src/levels/remote/mergeManyFeatures.js b/src/levels/remote/mergeManyFeatures.js index e9d2223e..e544c050 100644 --- a/src/levels/remote/mergeManyFeatures.js +++ b/src/levels/remote/mergeManyFeatures.js @@ -1,32 +1,40 @@ exports.level = { "goalTreeString": "{\"branches\":{\"master\":{\"target\":\"C11\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\",\"localBranchesThatTrackThis\":null},\"o/master\":{\"target\":\"C11\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":[\"master\"]},\"side1\":{\"target\":\"C2\",\"id\":\"side1\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null},\"side2\":{\"target\":\"C4\",\"id\":\"side2\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null},\"side3\":{\"target\":\"C7\",\"id\":\"side3\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C3\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C1\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C5\"],\"id\":\"C6\"},\"C7\":{\"parents\":[\"C6\"],\"id\":\"C7\"},\"C8\":{\"parents\":[\"C1\"],\"id\":\"C8\"},\"C9\":{\"parents\":[\"C2\",\"C8\"],\"id\":\"C9\"},\"C10\":{\"parents\":[\"C4\",\"C9\"],\"id\":\"C10\"},\"C11\":{\"parents\":[\"C10\",\"C7\"],\"id\":\"C11\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C11\",\"id\":\"master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C8\":{\"parents\":[\"C1\"],\"id\":\"C8\"},\"C5\":{\"parents\":[\"C1\"],\"id\":\"C5\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C6\":{\"parents\":[\"C5\"],\"id\":\"C6\"},\"C4\":{\"parents\":[\"C3\"],\"id\":\"C4\"},\"C9\":{\"parents\":[\"C2\",\"C8\"],\"id\":\"C9\"},\"C7\":{\"parents\":[\"C6\"],\"id\":\"C7\"},\"C10\":{\"parents\":[\"C4\",\"C9\"],\"id\":\"C10\"},\"C11\":{\"parents\":[\"C10\",\"C7\"],\"id\":\"C11\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", - "solutionCommand": "git checkout master;git pull;git merge side1;git merge side2;git merge side3;git push", + "solutionCommand": "git checkout main;git pull;git merge side1;git merge side2;git merge side3;git push", "startTree": "{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\",\"localBranchesThatTrackThis\":null},\"o/master\":{\"target\":\"C1\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":[\"master\"]},\"side1\":{\"target\":\"C2\",\"id\":\"side1\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null},\"side2\":{\"target\":\"C4\",\"id\":\"side2\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null},\"side3\":{\"target\":\"C7\",\"id\":\"side3\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C3\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C1\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C5\"],\"id\":\"C6\"},\"C7\":{\"parents\":[\"C6\"],\"id\":\"C7\"}},\"HEAD\":{\"target\":\"side3\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C8\",\"id\":\"master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C8\":{\"parents\":[\"C1\"],\"id\":\"C8\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", "name": { "en_US": "Merging with remotes", "zh_CN": "合并远程仓库", "zh_TW": "merge with remotes", "es_AR": "Mergeando con los remotos", + "es_ES": "Haciendo merge con los remotos", "pt_BR": "Merge com remotos", + "gl" : "Merge cos repos remotos", "de_DE": "Änderungen vom Remote zusammenführen", "ja" : "リモートとのmerge", "fr_FR": "Fusionner avec les branches distantes", "ru_RU": "Слияние с удалённым репозиторием", "ko" : "원격 작업과 merge하기", - "uk" : "Мердж з віддаленим репозиторієм" + "uk" : "Мердж з віддаленим репозиторієм", + "vi" : "Hợp nhất nhánh từ xa", + "sl_SI": "Merganje z oddaljenim repozitorijem" }, "hint": { "en_US": "Pay attention to the goal tree!", "zh_CN": "注意目标树!", "zh_TW": "注意最後要完成的目標!", "es_AR": "¡Prestá atención al árbol final!", + "es_ES": "¡Presta atención al árbol final!", "pt_BR": "Preste atenção na árvore do objetivo!", + "gl" : "Presta atención á arbore final!", "de_DE": "Beachte den Ziel-Baum!", "ja" : "ゴールツリーをよく見てください!", "fr_FR": "Respectez l'arbre représentant l'objectif !", "ru_RU": "Внимательно посмотрите на цель уровня!", "ko" : "goal을 잘 살펴보세요!", - "uk" : "Уважно подивись як має виглядати результат!" + "uk" : "Уважно подивись як має виглядати результат!", + "vi" : "Hãy để ý đến cây mục tiêu!", + "sl_SI": "Poglej si ciljno drevo!" }, "compareOnlyMaster": true, "startDialog": { @@ -38,7 +46,7 @@ exports.level = { "markdowns": [ "## Why not merge?", "", - "In order to push new updates to the remote, all you need to do is *incorporate* the latest changes from the remote. That means you can either rebase *or* merge in the remote branch (e.g. `o/master`).", + "In order to push new updates to the remote, all you need to do is *incorporate* the latest changes from the remote. That means you can either rebase *or* merge in the remote branch (e.g. `o/main`).", "", "So if you can do either method, why have the lessons focused on rebasing so far? Why is there no love for `merge` when working with remotes?", "" @@ -83,7 +91,7 @@ exports.level = { "markdowns": [ "## Pourquoi pas merge ?", "", - "Dans le but d'envoyer de nouvelles modifications sur le dépôt distant, la seule étape préliminaire est *d'incorporer* les derniers changements de ce dépôt dans le nôtre. Concrètement, vous pouvez faire un rebase *ou* un merge de la branche distante (c'est à dire de `o/master`).", + "Dans le but d'envoyer de nouvelles modifications sur le dépôt distant, la seule étape préliminaire est *d'incorporer* les derniers changements de ce dépôt dans le nôtre. Concrètement, vous pouvez faire un rebase *ou* un merge de la branche distante (c'est à dire de `o/main`).", "", "Donc si l'on peut faire les deux méthodes, pourquoi les leçons se sont-elles concentrées sur rebase jusqu'à présent ? Pourquoi préfère-t-on souvent éviter `merge` lorsque l'on travaille avec les branches distantes ?", "" @@ -128,7 +136,7 @@ exports.level = { "markdowns": [ "## ¿Por qué no mergear?", "", - "Para pushear tus novedades al remoto, todo lo que tenés que hacer es *integrar* los últimos cambios del remoto con los tuyos. Eso significa que podés hacer tanto rebase como merge con la rama remota (por ejemplo, `o/master`).", + "Para pushear tus novedades al remoto, todo lo que tenés que hacer es *integrar* los últimos cambios del remoto con los tuyos. Eso significa que podés hacer tanto rebase como merge con la rama remota (por ejemplo, `o/main`).", "", "Así que si podés hacer cualquiera de las dos, ¿por qué las lecciones sólo se centraron en rebasear hasta ahora? ¿Por qué no dedicarle algo de amor al `merge` cuando trabajamos con remotos?", "" @@ -165,6 +173,51 @@ exports.level = { } ] }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## ¿Por qué no hacer merge?", + "", + "Para hacer push con tus novedades al remoto, todo lo que tienes que hacer es *integrar* los últimos cambios del remoto con los tuyos. Eso significa que puedes hacer tanto rebase como merge con la rama remota (por ejemplo, `o/main`).", + "", + "Así que si puedes hacer cualquiera de las dos, ¿por qué las lecciones sólo se han centrado en rebasear hasta ahora? ¿Por qué no dedicarle algo de amor al `merge` cuando trabajamos con remotos?", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Hay mucho debate entre los desarrolladores sobre los pros y contras de mergear vs rebasear. Aquí te mostraré los pros y contras de rebasear:", + "", + "Pros:", + "", + "* Rebasear hace que tu árbol de commits se vea bastante limpio, porque todos los commits siguen una única línea", + "", + "Contras:", + "", + "* Rebasear modifica la historia (aparente) de tu árbol de commits.", + "", + "Por ejemplo, el commit `C1` puede rebasearse para que aparezca *después* de `C3`. Entonces, parece que el trabajo de `C1'` se hizo después de `C3`, cuando en realizad se había hecho antes.", + "", + "Algunos desarrolladores prefieren preservar la historia, por lo que deciden mergear. Otros (como yo) preferimos tener un árbol de commits limpios, y preferimos rebasear. Todo es una cuestión de preferencias :D" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para este nivel, tratemos de resolver el nivel anterior, pero *mergeando*. Puede volverse un poco cuesta arriba, pero ilustra la idea bastante bien." + ] + } + } + ] + }, "pt_BR": { "childViews": [ { @@ -173,7 +226,7 @@ exports.level = { "markdowns": [ "## Por que não um merge?", "", - "Para enviar novas atualizações ao repositório remoto, tudo que você precisa é *incorporar* as últimas mudanças ali presentes. Isso significa que você pode tanto fazer um rebase *quanto* um merge no ramo remoto (ex. `o/master`).", + "Para enviar novas atualizações ao repositório remoto, tudo que você precisa é *incorporar* as últimas mudanças ali presentes. Isso significa que você pode tanto fazer um rebase *quanto* um merge no ramo remoto (ex. `o/main`).", "", "Então, se você pode escolher qualquer um desses métodos, por que as lições focaram no rebase até o momento? Por que não demos nenhum amor ao `merge` quando trabalhamos com repositórios remotos?", "" @@ -210,6 +263,51 @@ exports.level = { } ] }, + "gl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## ¿Por qué non mesturar?", + "", + "Para empurrar as túas novidades ó remoto, todo o que tes que facer é *integrar* os últimos cambios do remoto cos teus. Eso significa que podes facer tanto rebase como merge ca rama remota (por exemplo, `o/main`).", + "", + "Así que podes facer calquera das dúas, ¿por qué as leccións só se centraron en rebasar ata agora? ¿Por qué non adicarlle algo de amor ó `merge` cando traballamos con remotos?", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Hai moito debate entre os desenvolvedores sobre os pros e contras de mesturar vs rebasar. Aquí temos os pros e os contras de rebasar:", + "", + "Pros:", + "", + "* Rebasar fai que a túa árbore de commits sexa bastante limpa, xa que tódolos commits seguen unha única línea.", + "", + "Contras:", + "", + "* Rebasar modifica a historia (aparente) da túa árbore de commits.", + "", + "Por exemplo, o commit `C1` pode rebasarse para que apareza *despois* de `C3`. Entón, parece que o traballo de `C1'` fíxose despois de `C3`, inda que na realidade fixérase antes.", + "", + "Algúns desenvolvedores aman preservar a historia, polo que prefiren mesturar. Outros (coma min) preferimos ter unha árbore de commits limpos, e preferimos rebasar. Todo é unha cuestión de preferencias :D" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para este nivel, tratemos de resolvelo nivel anterior, pero *mesturando*. Pode poñerse un pouco oscuro, pero ilustra a idea bastante ben." + ] + } + } + ] + }, "zh_TW": { "childViews": [ { @@ -218,7 +316,7 @@ exports.level = { "markdowns": [ "## 為何不要 merge?", "", - "為了要 push 新的 commit 給 remote,你只需要做的是先同步 remote 的更新,那就表示你可以使用 rebase *或者*是 merge remote branch (例如,`o/master`)。", + "為了要 push 新的 commit 給 remote,你只需要做的是先同步 remote 的更新,那就表示你可以使用 rebase *或者*是 merge remote branch (例如,`o/main`)。", "", "所以假如你已經學會使用其中一個方式了,那為什麼我們到目前為止還在強調 `rebase`?為什麼當提到 remote 的時候,反而 `merge` 比較沒有受到關注?", "" @@ -263,7 +361,7 @@ exports.level = { "markdowns": [ "## Warum nicht Merge?", "", - "Um neue Dinge auf das Remote zu schieben musst du erst alle Änderungen vom Remote holen und bei dir integrieren. Das bedeutet du kannst den entfernten Branch (z.B. `o/master`) entweder Rebasen *oder* Mergen.", + "Um neue Dinge auf das Remote zu schieben musst du erst alle Änderungen vom Remote holen und bei dir integrieren. Das bedeutet du kannst den entfernten Branch (z.B. `o/main`) entweder Rebasen *oder* Mergen.", "", "Wenn du also beide Methoden benutzen kannst, warum haben sich die Level bisher auf Rebase konzentriert? Warum mag keiner `merge` wenn es um Remotes geht?", "" @@ -278,7 +376,7 @@ exports.level = { "", "Vorteile:", "", - "* Rebasen macht den Commit-Baum sehr übersichtlich, weil alles linear aufeinander aufbaut", + "* Rebasen macht den Commit-Baum sehr übersichtlich, weil alles linear aufeinander aufbaut.", "", "Nachteile:", "", @@ -286,7 +384,7 @@ exports.level = { "", "Zum Beispiel kann durch Rebasen Commit `C1` an Commit `C3` *vorbei* bewegt werden, bzw. eine Kopie von `C1`. Es sieht dann so aus als wären die Änderungen in `C1` nach denen in `C3` gemacht worden, obwohl das nicht stimmt.", "", - "Manche Entwickler möchten lieber die History lassen wie sie ist und ziehen daher das Mergen vor. Andere (wie ich) haben lieber einen sauberen Commit-Baum und ziehen Rebase vor. Am Ende ist es eine Geschmacksfrage. :D" + "Manche Entwickler möchten lieber die History lassen, wie sie ist und ziehen daher das Mergen vor. Andere (wie ich) haben lieber einen sauberen Commit-Baum und ziehen Rebase vor. Am Ende ist es eine Geschmacksfrage. :D" ] } }, @@ -308,7 +406,7 @@ exports.level = { "markdowns": [ "## 为什么不用 merge 呢?", "", - "为了 push 新变更到远程仓库,你要做的就是**包含**远程仓库中最新变更。意思就是只要你的本地分支包含了远程分支(如 `o/master`)中的最新变更就可以了,至于具体是用 rebase 还是 merge,并没有限制。", + "为了 push 新变更到远程仓库,你要做的就是**包含**远程仓库中最新变更。意思就是只要你的本地分支包含了远程分支(如 `o/main`)中的最新变更就可以了,至于具体是用 rebase 还是 merge,并没有限制。", "", "那么既然没有规定限制,为何前面几节都在着重于 rebase 呢?为什么在操作远程分支时不喜欢用 `merge` 呢?", "" @@ -353,7 +451,7 @@ exports.level = { "markdowns": [ "## なぜマージではいけないのか?", "", - "新しい更新をリモートにプッシュするため、あなたがする必要があるのはリモートからの最近の変更の*組み込み*です。それは、リモートブランチ(例えば、`o/master`)にリベース*か*マージのどちらかをあなたがする必要があるということを意味します。", + "新しい更新をリモートにプッシュするため、あなたがする必要があるのはリモートからの最近の変更の*組み込み*です。それは、リモートブランチ(例えば、`o/main`)にリベース*か*マージのどちらかをあなたがする必要があるということを意味します。", "", "もしどっちの方法でも行うことができるなら、なぜこれまでのレッスンでは、リベースに焦点を当ててきたのでしょう?リモートへの作業で、なぜ`merge`を推してこなかったのでしょうか?", "" @@ -398,7 +496,7 @@ exports.level = { "markdowns": [ "## Merge? Нет, нет, спасибо.", "", - "Чтобы закачать (push) новые изменения в удалённый репозиторий, всё, что вам нужно сделать - это *смешать* последние изменения из удалённого репозитория. Это значит, что вы можете выполнить rebase *или* merge на удалённом репозитории (например, `o/master`).", + "Чтобы закачать (push) новые изменения в удалённый репозиторий, всё, что вам нужно сделать - это *смешать* последние изменения из удалённого репозитория. Это значит, что вы можете выполнить rebase *или* merge на удалённом репозитории (например, `o/main`).", "", "Если мы можем воспользоваться одним из двух методов, то почему же эти упражнения сфокусированы в основном на rebase? К чему такая нелюбовь к `merge`, когда речь идёт о работе с удалёнными репозиториями?", "" @@ -443,7 +541,7 @@ exports.level = { "markdowns": [ "## 왜 merge하지 않는거죠?", "", - "새로운 작업들을 원격 저장소로 push하기위해서 여러분은 원격 저장소의 최근 변경들을 *합치기*만 하면 됩니다. 이 말은 즉 원격 브랜치로(예:`o/master`) rebase를 할 수도 merge를 할 수도 있다는 것입니다.", + "새로운 작업들을 원격 저장소로 push하기위해서 여러분은 원격 저장소의 최근 변경들을 *합치기*만 하면 됩니다. 이 말은 즉 원격 브랜치로(예:`o/main`) rebase를 할 수도 merge를 할 수도 있다는 것입니다.", "", "두가지를 다 할 수 있다면, 왜 지금까지 배운 레슨들은 rebase를 하는것에 집중한거죠? 원격 저장소와 작업을 할때는 왜 `merge`에게 관심을 가져주지 않는건가요?", "" @@ -488,7 +586,7 @@ exports.level = { "markdowns": [ "## Чому б не змерджити?", "", - "Для того, щоб віддалений сервер прийняв твої зміни, треба *об'єднати* їх з останніми змінами на сервері. Це означає ребейс *або* мердж з віддаленою гілкою (напр. `o/master`).", + "Для того, щоб віддалений сервер прийняв твої зміни, треба *об'єднати* їх з останніми змінами на сервері. Це означає ребейс *або* мердж з віддаленою гілкою (напр. `o/main`).", "", "Хмм, якщо можна використати один із цих методів, для чого нам додаткові уроки про ребейс? Чому ніхто не любить `merge`, працюючи з віддаленим сервером?", "" @@ -524,6 +622,96 @@ exports.level = { } } ] + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Tại sao không hợp nhất?", + "", + "Để có thể đẩy cập nhật của bạn lên kho nhánh từ xa, tất cả những gì bạn cần làm là *kết nạp* thay đổi mới nhất từ nhánh từ xa. Nghĩa là bạn có thể dùng tái bố trí *hoặc* hợp nhất với nhánh từ xa (ví dụ `o/main`).", + "", + "Vậy ta có thể sử dụng một trong 2 cách, thì tại sao đến giờ ta chỉ tập trung vào tái bố trí trong các bài học? Tại sao khi làm việc với nhánh từ xa lại ta lại không thích `hợp nhất` (`merge`)?", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Trong cộng đồng phát triền phần mềm có rất nhiều tranh luận về ưu, nhươc, khuyết của việc sử dụng tái bố trí(`rebase`) hay hợp nhất(`merge`). Dưới đây là một vài ưu / nhược cơ bản của tái bố trí:", + "", + "Ưu điểm:", + "", + "* Tái bố trí làm cây commit của bạn trông gọn gàng hơn nhiều vì mọi thứ được xếp theo đường thẳng", + "", + "Nhược điểm:", + "", + "* Tái bố trí sửa đổi lịch sử (biểu hiện) của cây commit.", + "", + "Ví dụ, commit `C1` có thể bố trí lên *sau* `C3`. Thế là `C1'` biểu hiện như là nó xuất hiện sau `C3` trong khi thực tế nó được hoàn thành trước đó.", + "", + "Có những nhà phát triển muốn tôn trọng tính lịch sự nên họ ưa thích hợp nhất hơn. Những người khác (như tôi chẳng hạn) thì thiên về tái bố trí hơn vì muốn có cây commit gọn gàng. Rốt cục cũng là thiên hướng thôi :D" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Ở cấp độ này, hãy thử giải bài tập trước nhưng mà với *hợp nhất*. Có lẽ bài này hơi thừa nhưng mà nó mịnh họa quan điểm trên rõ ràng hơn." + ] + } + } + ] + }, + "sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Zakaj ne merganje?", + "", + "Da bi poslal nove spremembe na oddaljen repo, je vse kar moraš narediti, da *vključiš* zadnje spremembe iz oddaljenega repota. To pomeni, da lahko rebaseaš *ali* mergeaš v oddaljeni branch (npr. `o/main`).", + "", + "Torej če lahko narediš katero izmed metod, zakaj imeti lekcijo, ki se zaenkrat osredotoča na rebaseanje? Zakaj ni nobene ljubezni do `mergea` pri delanju z oddaljenimi repoti?", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Veliko govora je o kompromisih med merganjem in rebasanjem med razvijalci. Tu so splošne prednosti / slabosti rebaseanja:", + "", + "Prednosti:", + "", + "* Rebasanje naredi tvoje drevo lepo in pregledno, ker je vse v ravni črti", + "", + "Slabosti:", + "", + "* Rebasanje spremeni (navidezno) zgodovino drevesa commitov.", + "", + "Naprimer, commit `C1` je lahko rebasean *mimo* `C3`. Potem izgleda, kot da je delo za `C1'` prišlo za `C3`, čeprav je v resnici bilo končano prej.", + "", + "Nekateri razvijalci imajo radi ohranjanje zgodovine in imajo posledično rajši merganje. Drugi (kot jaz) imajo rajši čisto drevo commitov in posledično rebasanje. Na koncu prevlada osebna preferenca. :D" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Za to stopnjo, poizkusimo rešiti prešnjo stopnjo z *merganjem*. Mogoče bo malo zakomplicirano, vendar bo lepo ponazorilo poanto." + ] + } + } + ] } } }; diff --git a/src/levels/remote/pull.js b/src/levels/remote/pull.js index d1fa8cf9..d3e11689 100644 --- a/src/levels/remote/pull.js +++ b/src/levels/remote/pull.js @@ -7,26 +7,34 @@ exports.level = { "zh_CN": "Git Pull", "zh_TW": "git pull", "es_AR": "git pull", + "es_ES": "git pull", "pt_BR": "Git Pull", + "gl" : "Git Pull", "de_DE": "Git Pull", "ja" : "Git Pull", "fr_FR": "Git pull", "ru_RU": "Git pull", "uk" : "Git pull", - "ko" : "Git pull" + "ko" : "Git pull", + "vi" : "Git pull", + "sl_SI": "Git Pull" }, "hint": { "en_US": "Just run git pull!", "zh_CN": "运行 git pull 命令就可以了!", "zh_TW": "只要下 git pull 這個指令即可", "es_AR": "Simplemente ¡hacé git pull!", + "es_ES": "Simplemente ¡ejecuta git pull!", "pt_BR": "Basta executar git pull!", + "gl" : "Sinxelamente fai git pull!", "de_DE": "Führe einfach git pull aus.", "ja" : "単にgit pullを実行!", "fr_FR": "Utilisez facilement git pull !", "ru_RU": "Запустите комманду git pull !", "uk" : "Просто виконай git pull !", - "ko" : "그냥 git pull을 하세요!" + "ko" : "그냥 git pull을 하세요!", + "vi" : "Đơn giản là gõ git pull!", + "sl_SI": "Samo izvedi git pull!" }, "startDialog": { "en_US": { @@ -41,9 +49,9 @@ exports.level = { "", "There are actually many ways to do this -- once you have new commits available locally, you can incorporate them as if they were just normal commits on other branches. This means you could execute commands like:", "", - "* `git cherry-pick o/master`", - "* `git rebase o/master`", - "* `git merge o/master`", + "* `git cherry-pick o/main`", + "* `git rebase o/main`", + "* `git merge o/main`", "* etc., etc.", "", "In fact, the workflow of *fetching* remote changes and then *merging* them is so common that git actually provides a command that does both at once! That command is `git pull`." @@ -54,12 +62,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Let's first see a `fetch` and a `merge` executed sequentially" + "Let's first see a `fetch` and a `merge` executed sequentially." ], "afterMarkdowns": [ - "Boom -- we downloaded `C3` with a `fetch` and then merged in that work with `git merge o/master`. Now our `master` branch reflects the new work from the remote (in this case, named `origin`)" + "Boom -- we downloaded `C3` with a `fetch` and then merged in that work with `git merge o/main`. Now our `main` branch reflects the new work from the remote (in this case, named `origin`)" ], - "command": "git fetch; git merge o/master", + "command": "git fetch; git merge o/main", "beforeCommand": "git clone; git commit; git fakeTeamwork" } }, @@ -100,9 +108,9 @@ exports.level = { "", "Il existe en fait beaucoup de façons de faire cela -- une fois que vous avez de nouveaux commits disponibles localement, vous pouvez les incorporer dans votre branche de travail comme s'ils étaient des commits normaux d'autres branches. Cela signifie que pourriez simplement exécuter des commandes comme :", "", - "* `git cherry-pick o/master`", - "* `git rebase o/master`", - "* `git merge o/master`", + "* `git cherry-pick o/main`", + "* `git rebase o/main`", + "* `git merge o/main`", "* etc., etc.", "", "En fait, le principe de *rapatrier* (fetch) les branches distantes puis les *fusionner* (merge) est si commun que git a en réalité une commande pour faire les deux à la fois ! Cette commande est `git pull`." @@ -113,12 +121,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Voyons d'abord un `fetch` puis un `merge` exécutés séquentiellement" + "Voyons d'abord un `fetch` puis un `merge` exécutés séquentiellement." ], "afterMarkdowns": [ - "Boum -- nous avons téléchargé `C3` avec un `fetch` et ensuite nous avons fusionné ce travail dans notre copie avec `git merge o/master`. Maintenant notre branche `master` reflète le nouveau travail du dépôt distant (dans ce cas, nommé `origin`)" + "Boum -- nous avons téléchargé `C3` avec un `fetch` et ensuite nous avons fusionné ce travail dans notre copie avec `git merge o/main`. Maintenant notre branche `main` reflète le nouveau travail du dépôt distant (dans ce cas, nommé `origin`)" ], - "command": "git fetch; git merge o/master", + "command": "git fetch; git merge o/main", "beforeCommand": "git clone; git commit; git fakeTeamwork" } }, @@ -159,9 +167,9 @@ exports.level = { "", "Realmente hay varias formas de hacer esto: una vez que tenés los commits disponibles localmente, podés integrarlos como si fueran commits comunes de otras ramas. Esto significa que podrías ejecutar comandos como:", "", - "* `git cherry-pick o/master`", - "* `git rebase o/master`", - "* `git merge o/master`", + "* `git cherry-pick o/main`", + "* `git rebase o/main`", + "* `git merge o/main`", "* etc., etc.", "", "De hecho, el flujo de trabajo de *fetchear* cambios remotos y después *mergearlos* es tan común que git incluye un comando que hace ambas cosas de una: ¡`git pull`!" @@ -172,12 +180,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Veamos primero un `fetch` y un `merge` ejecutados secuencialmente" + "Veamos primero un `fetch` y un `merge` ejecutados secuencialmente." ], "afterMarkdowns": [ - "Boom: descargamos `C3` con un `fetch` y luego lo mergeamos con `git merge o/master`. Ahora nuestra rama `master` refleja el nuevo trabajo del remoto (en este caso, llamado `origin`)" + "Boom: descargamos `C3` con un `fetch` y luego lo mergeamos con `git merge o/main`. Ahora nuestra rama `main` refleja el nuevo trabajo del remoto (en este caso, llamado `origin`)" ], - "command": "git fetch; git merge o/master", + "command": "git fetch; git merge o/main", "beforeCommand": "git clone; git commit; git fakeTeamwork" } }, @@ -206,6 +214,65 @@ exports.level = { } ] }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Pull", + "", + "Ahora que vimos cómo traer datos de un repositorio remoto con `git fetch`, ¡actualicemos nuestro trabajo local para reflejar esos cambios!", + "", + "Realmente hay varias formas de hacer esto: una vez que tienes los commits disponibles localmente, puedes integrarlos como si fueran commits comunes de otras ramas. Esto significa que podrías ejecutar comandos como:", + "", + "* `git cherry-pick o/main`", + "* `git rebase o/main`", + "* `git merge o/main`", + "* etc., etc.", + "", + "De hecho, el flujo de trabajo de *fetchear* cambios remotos y después *mergearlos* es tan común que git incluye un comando que hace ambas cosas de una: ¡`git pull`!" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Veamos primero un `fetch` y un `merge` ejecutados secuencialmente." + ], + "afterMarkdowns": [ + "Zas: descargamos `C3` con un `fetch` y luego lo mergeamos con `git merge o/main`. Ahora nuestra rama `main` refleja el nuevo trabajo del remoto (en este caso, llamado `origin`)" + ], + "command": "git fetch; git merge o/main", + "beforeCommand": "git clone; git commit; git fakeTeamwork" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "¿Qué pasaría si en cambio utilizásemos `git pull`?" + ], + "afterMarkdowns": [ + "¡Lo mismo! Eso debería dejar bien claro que `git pull` es básicamente un atajo para hacer `git fetch` seguido por un merge con la rama que hayamos descargado." + ], + "command": "git pull", + "beforeCommand": "git clone; git commit; git fakeTeamwork" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Exploraremos los detalles de `git pull` después (incluyendo sus opciones y parámetros), pero por ahora probémoslo en este nivel.", + "", + "Recuerda: puedes ejecutar este comando simplemente con `fetch` y `merge`, pero eso te costaría un comando extra :P" + ] + } + } + ] + }, "pt_BR": { "childViews": [ { @@ -218,9 +285,9 @@ exports.level = { "", "Há, na verdade, muitas formas de fazê-lo -- uma vez que você tenha os novos commits disponíveis localmente, você pode incorporá-los como se eles fossem commits normais em outros ramos. Isso significa que você pode executar comandos como estes a seguir:", "", - "* `git cherry-pick o/master`", - "* `git rebase o/master`", - "* `git merge o/master`", + "* `git cherry-pick o/main`", + "* `git rebase o/main`", + "* `git merge o/main`", "* etc., etc.", "", "O fluxo de trabalho de executar *fetch* para baixar as mudanças remotas e depois fazer um *merge* delas é tão comum que o Git na verdade fornece um comando que faz ambas as coisas de uma vez só! Esse comando é o `git pull`." @@ -231,12 +298,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Vamos primeiro ver um `fetch` e um `merge` executados sequencialmente" + "Vamos primeiro ver um `fetch` e um `merge` executados sequencialmente." ], "afterMarkdowns": [ - "Boom -- nós baixamos o `C3` com um `fetch` e então fizemos um merge desse trabalho usando `git merge o/master`. Agora o nosso ramo `master` reflete o trabalho realizado no repositório remoto (neste caso, chamado de `origin`)" + "Boom -- nós baixamos o `C3` com um `fetch` e então fizemos um merge desse trabalho usando `git merge o/main`. Agora o nosso ramo `main` reflete o trabalho realizado no repositório remoto (neste caso, chamado de `origin`)" ], - "command": "git fetch; git merge o/master", + "command": "git fetch; git merge o/main", "beforeCommand": "git clone; git commit; git fakeTeamwork" } }, @@ -265,6 +332,65 @@ exports.level = { } ] }, + "gl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Pull", + "", + "Agora que vimos cómo traer os datos dun repositorio remoto con `git fetch`, ¡actualicemos o noso traballo local para reflexar eses cambios!", + "", + "Realmente hai varias formas de facer esto: unha vez que teñas os commits dispoñibles localmente, podes integralos coma se foran commits comúns de outras ramas. Esto significa que poderías executar comandos como:", + "", + "* `git cherry-pick o/main`", + "* `git rebase o/main`", + "* `git merge o/main`", + "* etc., etc.", + "", + "De feito, o fluxo de traballo de *fetchear* os cambios remotos e depois *mesturalos* é tan común que git inclúe un comando que fai as dúas operacións nunha sola: ¡`giti pull`!" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Vexamos primeiro un `fetch` e un `merge` executados secuencialmente." + ], + "afterMarkdowns": [ + "Boom: descargamos `C3` cun `fetch` e logo mesturámolos con `git merge o/main`. Agora a nosa rama `main` reflexa o novo traballo do remoto (neste caso, chamado `origin`)" + ], + "command": "git fetch; git merge o/main", + "beforeCommand": "git clone; git commit; git fakeTeamwork" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "¿Qué pasaría se usáramos `git pull` en cambio?" + ], + "afterMarkdowns": [ + "¡O mesmo! Eso debía deixar ben claro que `git pull` é básicamente un atallo para facer `git fetch` seguido pola mestura ca rama que houbésemos descargado." + ], + "command": "git pull", + "beforeCommand": "git clone; git commit; git fakeTeamwork" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Exploraremos os detalles de `git pull` despois (incluíndo as súas operacións e parámetros), pero por agora probarémolo neste nivel.", + "", + "Lémbrate: podes resolver este comando sinxelamente con `fetch` e `merge`, pero eso costaríache un comando extra :P" + ] + } + } + ] + }, "zh_TW": { "childViews": [ { @@ -277,9 +403,9 @@ exports.level = { "", "只要在你的 local 有 fetch 到新的 commit,便有很多方法可以做到這件事情,你可以把它們視為在其它 branch 上面的一般的 commit,這表示你可以執行像這樣子的指令:", "", - "* `git cherry-pick o/master`", - "* `git rebase o/master`", - "* `git merge o/master`", + "* `git cherry-pick o/main`", + "* `git rebase o/main`", + "* `git merge o/main`", "* 等等‧‧‧", "", "事實上,一次*下載 (fetch)* remote 的更新並且*合併(merge)* 這些更新在 git 裡面是很常見的事情!這個命令叫作 `git pull`。" @@ -293,9 +419,9 @@ exports.level = { "讓我們來看循序執行一個 `fetch` 和一個 `merge` 的樣子" ], "afterMarkdowns": [ - "看吧! 我們利用 `fetch` 下載了 `C3` 並且利用 `git merge o/master` 來更新資料,現在我們的 `master` branch 跟 remote 同步了(在這個例子中,remote repository 叫作 `origin`)。" + "看吧! 我們利用 `fetch` 下載了 `C3` 並且利用 `git merge o/main` 來更新資料,現在我們的 `main` branch 跟 remote 同步了(在這個例子中,remote repository 叫作 `origin`)。" ], - "command": "git fetch; git merge o/master", + "command": "git fetch; git merge o/main", "beforeCommand": "git clone; git commit; git fakeTeamwork" } }, @@ -336,9 +462,9 @@ exports.level = { "", "其实有很多方法的 —— 当远程分支中有新的提交时,你可以像合并本地分支那样来合并远程分支。也就是说就是你可以执行以下命令: ", "", - "* `git cherry-pick o/master`", - "* `git rebase o/master`", - "* `git merge o/master`", + "* `git cherry-pick o/main`", + "* `git rebase o/main`", + "* `git merge o/main`", "* 等等", "", "实际上,由于先抓取更新再合并到本地分支这个流程很常用,因此 Git 提供了一个专门的命令来完成这两个操作。它就是我们要讲的 `git pull`。" @@ -352,9 +478,9 @@ exports.level = { "我们先来看看 `fetch`、`merge` 依次执行的效果" ], "afterMarkdowns": [ - "我们用 `fetch` 下载了 `C3`, 然后通过 `git merge o/master` 合并了这一提交记录。现在我们的 `master` 分支包含了远程仓库中的更新(在本例中远程仓库名为 `origin`)" + "我们用 `fetch` 下载了 `C3`, 然后通过 `git merge o/main` 合并了这一提交记录。现在我们的 `main` 分支包含了远程仓库中的更新(在本例中远程仓库名为 `origin`)" ], - "command": "git fetch; git merge o/master", + "command": "git fetch; git merge o/main", "beforeCommand": "git clone; git commit; git fakeTeamwork" } }, @@ -391,16 +517,16 @@ exports.level = { "markdowns": [ "## Git Pull", "", - "Jetzt, wo wir wissen wie wir mit `git fetch` Daten von einem entfernten Repository holen können, wollen wir unsere lokalen Daten aktualisieren, damit sie die Änderungen vom Server beinhalten.", + "Jetzt, wo wir wissen, wie wir mit `git fetch` Daten von einem entfernten Repository holen können, wollen wir unsere lokalen Daten aktualisieren, damit sie die Änderungen vom Server beinhalten.", "", - "Tatsächlich gibt es eine Menge Wege dies zu erreichen -- sobald du die neuen Commits lokal verfügbar hast, kannst du sie integrieren so als wären es Commits von ganz normalen anderen Branches. Du kannst also:", + "Tatsächlich gibt es eine Menge Wege dies zu erreichen -- sobald du die neuen Commits lokal verfügbar hast, kannst du sie integrieren wie Commits von ganz normalen anderen Branches. Du kannst also:", "", - "* `git cherry-pick o/master`", - "* `git rebase o/master`", - "* `git merge o/master`", + "* `git cherry-pick o/main`", + "* `git rebase o/main`", + "* `git merge o/main`", "* usw. usf. ausführen.", "", - "Der Ablauf, die Änderungen vom Server zu holen und dann in die eigene Arbeit zu mergen wird so häufig benötigt, dass Git einen Befehl kennt der beides auf einmal erledigt! Das ist `git pull`." + "Änderungen vom Server zu holen und dann in die eigene Arbeit zu mergen wird so häufig benötigt, dass Git einen Befehl kennt, der beides auf einmal erledigt! Das ist `git pull`." ] } }, @@ -411,9 +537,9 @@ exports.level = { "Schauen wir uns erst mal ein `fetch` gefolgt von `merge` an:" ], "afterMarkdowns": [ - "Bämm -- wir haben `C3` mit `fetch` heruntergeladen und dann in unseren Branch mit `git merge o/master` integriert. Nun bildet unser `master` dieselben Inhalte ab, wie sie auf dem entfernten Server (`origin`) liegen." + "Bämm -- wir haben `C3` mit `fetch` heruntergeladen und dann in unseren Branch mit `git merge o/main` integriert. Nun bildet unser `main` dieselben Inhalte ab, wie sie auf dem entfernten Server (`origin`) liegen." ], - "command": "git fetch; git merge o/master", + "command": "git fetch; git merge o/main", "beforeCommand": "git clone; git commit; git fakeTeamwork" } }, @@ -454,9 +580,9 @@ exports.level = { "", "Существует множество вариантов решений - как только у вас имеется локальный коммит, вы можете соединить его с другой веткой. Это значит, вы можете выполнить одну из команд:", "", - "* `git cherry-pick o/master`", - "* `git rebase o/master`", - "* `git merge o/master`", + "* `git cherry-pick o/main`", + "* `git rebase o/main`", + "* `git merge o/main`", "* и т.д.", "", "Процедура *скачивания (fetching)* изменений с удалённой ветки и *объединения (merging)* настолько частая и распространённая, что git предоставляет вместо двух команд - одну! Эта команда - `git pull`." @@ -470,9 +596,9 @@ exports.level = { "Давайте рассмотрим, как `fetch` и `merge` выполняются последовательно" ], "afterMarkdowns": [ - "Опа - мы скачали `C3` с помощью команды `fetch` и затем объединяем эти наработки с помощью `git merge o/master`. Теперь наша ветка `master` отображает изменения с удалённого репозитория (в данном случае — с репозитория `origin`)" + "Опа - мы скачали `C3` с помощью команды `fetch` и затем объединяем эти наработки с помощью `git merge o/main`. Теперь наша ветка `main` отображает изменения с удалённого репозитория (в данном случае — с репозитория `origin`)" ], - "command": "git fetch; git merge o/master", + "command": "git fetch; git merge o/main", "beforeCommand": "git clone; git commit; git fakeTeamwork" } }, @@ -513,9 +639,9 @@ exports.level = { "", "実際には多くの方法があり、ローカルに利用可能なリモートの新しいコミットがある場合、あなたはそのコミットを他のブランチの通常のコミットと同じように、自分の作業に組み込むことができます。これは、あなたが次のようなコマンドを実行することで行えます:", "", - "* `git cherry-pick o/master`", - "* `git rebase o/master`", - "* `git merge o/master`", + "* `git cherry-pick o/main`", + "* `git rebase o/main`", + "* `git merge o/main`", "* その他", "", "実は、リモートの変更を取ってきてマージするという作業の流れはとてもよく行われるので、gitは実際にはその二つを同時に行うコマンドを提供しているのです!それは、`git pull`というコマンドです。" @@ -529,9 +655,9 @@ exports.level = { "まずは、連続して`fetch`して`merge`する流れの方を見てみましょう。" ], "afterMarkdowns": [ - "わーお。私たちは`C3`を`fetch`でダウンロードして、`git merge o/master`でこれをマージしました。今や私たちの`master`ブランチに(この場合、`origin`という名前の)リモートの新しい作業内容が反映されています。" + "わーお。私たちは`C3`を`fetch`でダウンロードして、`git merge o/main`でこれをマージしました。今や私たちの`main`ブランチに(この場合、`origin`という名前の)リモートの新しい作業内容が反映されています。" ], - "command": "git fetch; git merge o/master", + "command": "git fetch; git merge o/main", "beforeCommand": "git clone; git commit; git fakeTeamwork" } }, @@ -572,9 +698,9 @@ exports.level = { "", "Насправді, є кілька шляхів як цого досягнути -- щойно нові коміти з’явилися локально, ти можеш додавати їх в бранчі так само, як звичайні коміти. Це означає що ти можеш виконувати команди:", "", - "* `git cherry-pick o/master`", - "* `git rebase o/master`", - "* `git merge o/master`", + "* `git cherry-pick o/main`", + "* `git rebase o/main`", + "* `git merge o/main`", "* тощо.", "", "Насправді, процес *витягування* віддалених змін й подальший *мерджинг* їх є настільки популярним, що гіт пропонує спеціальну команду, що виконує ці дві дії за один раз! Ця команда називається `git pull`." @@ -585,12 +711,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Спершу виконаймо по черзі `fetch`, а потім `merge`" + "Спершу виконаймо по черзі `fetch`, а потім `merge`." ], "afterMarkdowns": [ - "Ка-бум -- ми звантажили `C3` за допомогою `fetch` і потім змерджили їх, використавши `git merge o/master`. Тепер наша гілка `master` відповідає гілці з віддаленого сховища (в цьому випадку, з назвою `origin`)" + "Ка-бум -- ми звантажили `C3` за допомогою `fetch` і потім змерджили їх, використавши `git merge o/main`. Тепер наша гілка `main` відповідає гілці з віддаленого сховища (в цьому випадку, з назвою `origin`)" ], - "command": "git fetch; git merge o/master", + "command": "git fetch; git merge o/main", "beforeCommand": "git clone; git commit; git fakeTeamwork" } }, @@ -631,9 +757,9 @@ exports.level = { "", "사실 이걸 하는 방법은 여러가지 있습니다 -- 새 커밋들을 로컬에 내려받은 이후에는 그냥 다른 브랜치에있는 일반 커밋처럼 활용할 수 있습니다. 이런 명령들을 실행할 수 있다는 뜻 입니다 :", "", - "* `git cherry-pick o/master`", - "* `git rebase o/master`", - "* `git merge o/master`", + "* `git cherry-pick o/main`", + "* `git rebase o/main`", + "* `git merge o/main`", "* 기타 등등", "", "사실 원격 저장소의 변경을 *fetch*하고 그이후에 *merge*하는 작업의 과정이 워낙 자주있는 일이라서 git은 이 두가지를 한번에 하는 명령을 제공합니다! 이 명령어는 `git pull` 입니다." @@ -647,9 +773,9 @@ exports.level = { "먼저 `fetch` 와 `merge`가 차례로 실행되는것을 확인해 봅시다" ], "afterMarkdowns": [ - "Boom -- 우리는 `C3`를 `fetch`로 내려 받고 `git merge o/master`로 우리의 작업으로 병합했습니다. 이제 우리의 `master` 브랜치는 원격 저장소의 새 작업들을 반영하게 됩니다(지금 사례에서 `origin`입니다)." + "Boom -- 우리는 `C3`를 `fetch`로 내려 받고 `git merge o/main`로 우리의 작업으로 병합했습니다. 이제 우리의 `main` 브랜치는 원격 저장소의 새 작업들을 반영하게 됩니다(지금 사례에서 `origin`입니다)." ], - "command": "git fetch; git merge o/master", + "command": "git fetch; git merge o/main", "beforeCommand": "git clone; git commit; git fakeTeamwork" } }, @@ -677,6 +803,124 @@ exports.level = { } } ] + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Pull", + "", + "Ta đã biết cách dùng `git fetch` để nạp các commit từ kho chứa từ xa, giờ hãy cập nhật các commit này vào các nhánh địa phương!", + "", + "Thực ra thì có nhiều cách đề làm điều này -- một khi bạn đã có các commit này ở ko chứa địa phương, bạn có thể hợp nhất chúng như với các commit ở các nhánh khác. Nghĩa là bạn có thể sử dụng các câu lệnh sau:", + "", + "* `git cherry-pick o/main`", + "* `git rebase o/main`", + "* `git merge o/main`", + "* etc., etc.", + "", + "Thực tế thì, quá trình *nạp* commit từ kho chứa từ xa và *hợp nhất* chúng phổ biết đến nỗi git cung cấp một câu lệnh để làm cả 2 điều này một lúc! Đó là `git pull`." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Trước tiên hãy xem quá trình `nạp` và `hợp nhất` được thực hiện một cách tuần tự." + ], + "afterMarkdowns": [ + "Bùùm -- ta tải xuống commit `C3` với lệnh `git fetch` rồi sau đó hợp nhất nó với lệnh `git merge o/main`. Giờ thì nhánh `main` đã phản ánh trạng thái mới từ kho chứa từ xa (trong trường hợp này là `origin`)" + ], + "command": "git fetch; git merge o/main", + "beforeCommand": "git clone; git commit; git fakeTeamwork" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Nếu thay vì dó ta dùng `git pull` thì điều gì xảy ra?" + ], + "afterMarkdowns": [ + "Cũng như nhau! Điều đó có nghĩa là `git pull` về cơ bản là cách làm tắt cho việc thực hiện tuần tự `git fetch` sau đó là hợp nhất các nhánh từ xa được nạp." + ], + "command": "git pull", + "beforeCommand": "git clone; git commit; git fakeTeamwork" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Ta sẽ tìm hiều chi tiết về `git pull` sau (bao gồm các tùy chọn và tham số), còn bây giờ thì cứ dùng thử nó ở cấp độ này đã.", + "", + "Nhớ rằng -- bạn có thể giải quyết cấp độ này với `fetch` và sau đó `merge`, nhưng mà như thế thì lại tốn têm một câu lệnh :P" + ] + } + } + ] + }, + "sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Pull", + "", + "Sedaj, ko smo videli kako pridobiti podatke iz oddaljenega repozitorija z `git fetch`, posodobimo naše delo, da bo odsevalo te sprememebe!", + "", + "V bistvu je več načinov za izvedbo tega -- ko imaš enkrat lokalno na voljo nove commite, jih lahko vključiš, kot da so normalni commiti na drugem branchu. To pomeni, da lahko izvedeš ukaze, kot so:", + "", + "* `git cherry-pick o/main`", + "* `git rebase o/main`", + "* `git merge o/main`", + "* itd., itd.", + "", + "Pravzaprav je *fetchanje* oddaljenih sprememb in kasneje *merganje* le-teh tako pogosto, da ima git dejansko ukaz, ki naredi oboje! Ukaz je `git pull`." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Poglejmo najprej `fetch` in `merge` izvedena zaporedno:" + ], + "afterMarkdowns": [ + "Boom -- prenesli smo `C3` s `fetch` in nato mergali delo z `git merge o/main`. Sedaj naš `main` branch odseva spremembe novega dela iz oddaljenega repoztorija (v tem primeru poimenovan `origin`)." + ], + "command": "git fetch; git merge o/main", + "beforeCommand": "git clone; git commit; git fakeTeamwork" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Kaj bi se zgodilo, če bi namesto tega uporabili `git pull`?" + ], + "afterMarkdowns": [ + "Ista stvar! To bi moralo pokazati, da je `git pull` v bistvu bližnjica za `git fetch`, ki mu sledi merge brancha, ki smo ga ravno fetchali." + ], + "command": "git pull", + "beforeCommand": "git clone; git commit; git fakeTeamwork" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Kasneje bomo raziskali podrobnosti ukaza `git pull` (vključno z opcijami in argumenti), ampak zaenkrat poizkusimo brez v tej stopnji.", + "", + "Pomni -- to stopnjo lahko rešiš s `fetch` in `merge`, ampak boš rabil en dodaten ukaz :P" + ] + } + } + ] } } }; diff --git a/src/levels/remote/pullArgs.js b/src/levels/remote/pullArgs.js index a746ef3b..a7f62663 100644 --- a/src/levels/remote/pullArgs.js +++ b/src/levels/remote/pullArgs.js @@ -1,32 +1,40 @@ exports.level = { "goalTreeString": "{\"branches\":{\"master\":{\"target\":\"C6\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\"},\"o/master\":{\"target\":\"C1\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null},\"o/bar\":{\"target\":\"C1\",\"id\":\"o/bar\",\"remoteTrackingBranchID\":null},\"foo\":{\"target\":\"C3\",\"id\":\"foo\",\"remoteTrackingBranchID\":null},\"side\":{\"target\":\"C2\",\"id\":\"side\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C4\":{\"parents\":[\"C1\"],\"id\":\"C4\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C5\":{\"parents\":[\"C3\",\"C4\"],\"id\":\"C5\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C6\":{\"parents\":[\"C2\",\"C5\"],\"id\":\"C6\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\",\"remoteTrackingBranchID\":null},\"bar\":{\"target\":\"C3\",\"id\":\"bar\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"}},\"HEAD\":{\"target\":\"bar\",\"id\":\"HEAD\"}}}", - "solutionCommand": "git pull origin bar:foo;git pull origin master:side", + "solutionCommand": "git pull origin bar:foo;git pull origin main:side", "startTree": "{\"branches\":{\"master\":{\"target\":\"C4\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\"},\"o/master\":{\"target\":\"C1\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null},\"o/bar\":{\"target\":\"C1\",\"id\":\"o/bar\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C4\":{\"parents\":[\"C1\"],\"id\":\"C4\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\",\"remoteTrackingBranchID\":null},\"bar\":{\"target\":\"C3\",\"id\":\"bar\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"}},\"HEAD\":{\"target\":\"bar\",\"id\":\"HEAD\"}}}", "name": { "en_US": "Pull arguments", "zh_CN": "Git pull 的参数", "zh_TW": "pull 的參數", "es_AR": "Parámetros de pull", + "es_ES": "Parámetros de pull", "pt_BR": "Parâmetros do pull", + "gl" : "Parámetros de pull", "de_DE": "Optionen für Pull", "ja" : "Pullの引数", "fr_FR": "Arguments de pull", "ru_RU": "Аргументы для pull", "ko" : "pull 인자들", - "uk" : "Аргументи pull" + "uk" : "Аргументи pull", + "vi" : "Tham số pull", + "sl_SI": "Pull argumenti" }, "hint": { "en_US": "Remember that you can create new local branches with fetch/pull arguments", "zh_CN": "记住, 你可以通过 fetch/pull 创建本地分支", "zh_TW": "記住,你可以透過 fetch 以及 pull 來建立一個新的 local 的 branch", "es_AR": "Acordate de que podés crear nuevas ramas locales usando los parámetros de fetch/pull", + "es_ES": "Recuerda que puedes crear nuevas ramas locales usando los parámetros de fetch/pull", "pt_BR": "Lembre-se que você pode criar novos ramos locais com parâmetros de fetch/pull", + "gl" : "Lémbrate que podes crear novas ramas locais con parámetros de fetch/pull", "de_DE": "Du kannst neue lokale Branches mittels fetch / pull erstellen", "ja" : "Fetchとpullの引数を利用してローカルで新規ブランチを作成できるのをお忘れなく", "fr_FR": "Vous pouvez aussi créer une nouvelle branche locale avec les arguments de fetch/pull", "ru_RU": "Напоминаю, что новые ветки можно создавать и с помощью команд fetch/pull", "ko" : "fetch/pull 과 인자들로 새 로컬 브랜치를 생성할수 있다는것을 기억하세요.", - "uk" : "Пам'ятай, що ти можеш створювати нові гілки, використовуючи fetch/pull з аргументами" + "uk" : "Пам'ятай, що ти можеш створювати нові гілки, використовуючи fetch/pull з аргументами", + "vi" : "Nhớ rằng,bạn có thể tạo nhánh cục bộ mới với tham số của fetch/pull", + "sl_SI": "Zapomni si, da lahko ustvariš nove lokalne branche s fetch/pull argumenti." }, "startDialog": { "en_US": { @@ -71,12 +79,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "If we specify the place to fetch, everything happens as before with fetch but we merge in whatever was just fetched" + "If we specify the place to fetch, everything happens as before with fetch but we merge in whatever was just fetched." ], "afterMarkdowns": [ - "See! by specifying `master` we downloaded commits onto `o/master` just as normal. Then we merged `o/master` to where we are, *regardless* of what was currently checked out." + "See! by specifying `main` we downloaded commits onto `o/main` just as normal. Then we merged `o/main` to our currently checked out location which is *not* the local branch `main`. For this reason it can actually make sense to run git pull multiple times (with the same args) from different locations in order to update multiple branches." ], - "command": "git pull origin master", + "command": "git pull origin main", "beforeCommand": "git clone; go -b bar; git commit; git fakeTeamwork" } }, @@ -87,9 +95,9 @@ exports.level = { "Does it work with source and destination too? You bet! Let's see that:" ], "afterMarkdowns": [ - "Wow, that's a TON in one command. We created a new branch locally named `foo`, downloaded commits from remote's master onto that branch `foo`, and then merged that branch into our currently checked out branch `bar`. It's over 9000!!!" + "Wow, that's a TON in one command. We created a new branch locally named `foo`, downloaded commits from remote's main onto that branch `foo`, and then merged that branch into our currently checked out branch `bar`. It's over 9000!!!" ], - "command": "git pull origin master:foo", + "command": "git pull origin main:foo", "beforeCommand": "git clone; git fakeTeamwork; go -b bar; git commit" } }, @@ -148,9 +156,9 @@ exports.level = { "Si nous précisons l'emplacement à rapatrier tout se passe comme précédemment, avec fetch, mais en sus nous fusionnons tout ce qui a été rapatrié." ], "afterMarkdowns": [ - "Vu ? En précisant `master` nous avons téléchargé les commits dans `o/master` comme d'habitude. Puis nous avons fusionné `o/master` avec là où nous sommes, *sans nous soucier* de la branche courante." + "Vu ? En précisant `main` nous avons téléchargé les commits dans `o/main` comme d'habitude. Puis nous avons fusionné `o/main` avec là où nous sommes, *sans nous soucier* de la branche courante." ], - "command": "git pull origin master", + "command": "git pull origin main", "beforeCommand": "git clone; go -b bar; git commit; git fakeTeamwork" } }, @@ -161,9 +169,9 @@ exports.level = { "Cela fonctionne-t-il aussi bien avec une source et une destination ? Et oui ! Voyons cela :" ], "afterMarkdowns": [ - "Wow, INCROYABLE tout ce que nous avons fait en une commande. Nous avons créé une branche locale nommée `foo`, téléchargé les commits depuis la branche master distante dans `foo`, et ensuite fusionné cette branche dans notre branche actuelle de travail (checkoutée) `bar` !!!" + "Wow, INCROYABLE tout ce que nous avons fait en une commande. Nous avons créé une branche locale nommée `foo`, téléchargé les commits depuis la branche main distante dans `foo`, et ensuite fusionné cette branche dans notre branche actuelle de travail (checkoutée) `bar` !!!" ], - "command": "git pull origin master:foo", + "command": "git pull origin main:foo", "beforeCommand": "git clone; git fakeTeamwork; go -b bar; git commit" } }, @@ -219,12 +227,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Si especificamos el lugar del que hacer fetch, todo ocurre como antes, pero sólo mergeamos lo que se fetcheó" + "Si especificamos el lugar del que hacer fetch, todo ocurre como antes, pero sólo mergeamos lo que se fetcheó." ], "afterMarkdowns": [ - "¡Ves! Especificando `master` bajamos los commits a `o/master` como siempre. Después mergeamos `o/master` a nuestra rama actual, *sin importar* qué había en nuestra copia de trabajo." + "¡Ves! Especificando `main` bajamos los commits a `o/main` como siempre. Después mergeamos `o/main` a nuestra rama actual, *sin importar* qué había en nuestra copia de trabajo." ], - "command": "git pull origin master", + "command": "git pull origin main", "beforeCommand": "git clone; go -b bar; git commit; git fakeTeamwork" } }, @@ -235,9 +243,9 @@ exports.level = { "¿Esto funciona con origen y destino, también? ¡Más vale! Veámoslo:" ], "afterMarkdowns": [ - "Wow, eso es un MONTÓN en un único comando. Creamos una nueva rama local llamada `foo`, descargamos los commits del master del remoto a esta rama `foo`, y después mezclamos esa rama a nuestra rama actual `bar`. ¡¡¡Supera los 9000!!!" + "Wow, eso es un MONTÓN en un único comando. Creamos una nueva rama local llamada `foo`, descargamos los commits del main del remoto a esta rama `foo`, y después mezclamos esa rama a nuestra rama actual `bar`. ¡¡¡Supera los 9000!!!" ], - "command": "git pull origin master:foo", + "command": "git pull origin main:foo", "beforeCommand": "git clone; git fakeTeamwork; go -b bar; git commit" } }, @@ -251,6 +259,80 @@ exports.level = { } ] }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Parámetros de git pull", + "", + "Ahora que sabes prácticamente *todo* lo que hay que saber sobre los parámetros de `git fetch` y `git push`, casi no queda nada por cubrir del comando git pull :)", + "", + "Eso es porque git pull es simplemente un atajo para hacer un fetch seguido de un merge. Puedes imaginártelo como ejecutar git fetch con los *mismos* parámetros, y después hacer merge de ello hacia donde esos commits hayan ido a parar.", + "", + "Esto aplica incluso cuando utilizas parámetros rebuscados en exceso. Veamos algunos ejemplos:" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Estos son algunos comandos equivalentes de git:", + "", + "`git pull origin foo` equivale a:", + "", + "`git fetch origin foo; git merge o/foo`", + "", + "Y...", + "", + "`git pull origin bar~1:bugFix` equivale a:", + "", + "`git fetch origin bar~1:bugFix; git merge bugFix`", + "", + "¿Ves? git pull es simplemente un atajo para un fetch + merge, y todo lo que le importa a git pull es dónde terminaron esos commits (el parámetro `destino` que determina durante el fetch).", + "", + "Veamos una demostración:" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Si especificamos el lugar desde donde hacer fetch, todo ocurre como antes, pero sólo mergeamos lo que se fetcheó." + ], + "afterMarkdowns": [ + "¡Ves! Especificando `main` descargamos los commits a `o/main` como siempre. Después mergeamos `o/main` a nuestra rama actual, *sin importar* qué había en nuestra copia de trabajo." + ], + "command": "git pull origin main", + "beforeCommand": "git clone; go -b bar; git commit; git fakeTeamwork" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "¿Esto funciona con origen y destino, también? ¡Más vale! Veámoslo:" + ], + "afterMarkdowns": [ + "Caramba, eso es una BARBARIDAD en un único comando. Creamos una nueva rama local llamada `foo`, descargamos los commits del main del remoto a esta rama `foo`, y después mezclamos esa rama a nuestra rama actual `bar`. ¡¡¡Supera los 9000!!!" + ], + "command": "git pull origin main:foo", + "beforeCommand": "git clone; git fakeTeamwork; go -b bar; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "OK: para terminar, intenta alcanzar el estado del objetivo. Vas a necesitar descargar algunos commits, crear algunas ramas nuevas, y mergear esas ramas junto con otras, pero no debería llevar demasiados comandos :P" + ] + } + } + ] + }, "pt_BR": { "childViews": [ { @@ -293,12 +375,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Se especificarmos o lugar onde fazer o fetch, tudo acontece como antes com o fetch, mas fazemos o merge naquilo que acabou de ser baixado" + "Se especificarmos o lugar onde fazer o fetch, tudo acontece como antes com o fetch, mas fazemos o merge naquilo que acabou de ser baixado." ], "afterMarkdowns": [ - "Veja! Especificando `master` nós baixamos commits em `o/master` como sempre. Então fizemos um merge de `o/master` com o lugar onde estamos, *independente* daquilo que está atualmente em checkout." + "Veja! Especificando `main` nós baixamos commits em `o/main` como sempre. Então fizemos um merge de `o/main` com o lugar onde estamos, *independente* daquilo que está atualmente em checkout." ], - "command": "git pull origin master", + "command": "git pull origin main", "beforeCommand": "git clone; go -b bar; git commit; git fakeTeamwork" } }, @@ -309,9 +391,9 @@ exports.level = { "Isso também funciona com origem e destino especificados? Sim, você acertou! Vejamos:" ], "afterMarkdowns": [ - "Wow, isso é MUITA coisa em um comando só. Nós criamos um novo ramo local chamado `foo`, baixamos commits do master remoto nesse ramo `foo`, e então fizemos um merge dele com o ramo atualmente em checkout, `bar`." + "Wow, isso é MUITA coisa em um comando só. Nós criamos um novo ramo local chamado `foo`, baixamos commits do main remoto nesse ramo `foo`, e então fizemos um merge dele com o ramo atualmente em checkout, `bar`." ], - "command": "git pull origin master:foo", + "command": "git pull origin main:foo", "beforeCommand": "git clone; git fakeTeamwork; go -b bar; git commit" } }, @@ -325,6 +407,80 @@ exports.level = { } ] }, + "gl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Parámetros de git pull", + "", + "Agora que sabes prácticamente *todo* o que hai que saber sobre os parámetros de `git fetch` e `git push`, casi que non queda nada para cubrir os de git pull :D", + "", + "Eso é porque git pull é sinxelamente un atallo para facer un fetch seguido dun merge. Podes pensalo como executar git fetch cos *mesmos* parámetros, e logo mesturar aquelo onde esos commits houberan ido ficar.", + "", + "Esto aplica incluso cando usas parámetros hiper-complexos. Vexamos algúns exemplos:" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Estos son algúns comandos equivalentes de git:", + "", + "`git pull origin foo` equivale a:", + "", + "`git fetch origin foo; git merge o/foo`", + "", + "E...", + "", + "`git pull origin bar~1:bugFix` equivale a:", + "", + "`git fetch origin bar~1:bugFix; git merge bugFix`", + "", + "¿Ves? git pull é sinxelamente un atallo para un fetch + merge, e todo o que lle importa a git pull é ónde terminaron eses commits (o parámetro `destino` que indícase durante o fetch).", + "", + "Vexamos unha demostración:" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Se especificamos o lugar do que facer o fetch, todo ocorre coma antes, pero só mesturamos o que se descargou." + ], + "afterMarkdowns": [ + "¡Ves! Indicando `main` baixamos os commits á `o/main` coma sempre. Despois mesturamos `o/main` á nosa rama actual, *sen importar* qué tiñamos na nos copia de traballo." + ], + "command": "git pull origin main", + "beforeCommand": "git clone; go -b bar; git commit; git fakeTeamwork" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "¿Esto funciona co orixe e o destino, tamén? ¡Máis lle vale! Vexámolo:" + ], + "afterMarkdowns": [ + "Wow, eso es unha CHEA nun único comando. Creamos unha nova rama local chamada `foo`, descargamos os commits do main do remoto a esta rama `foo`, e logo mesturamos esa rama á nosa rama actual `bar`. ¡¡¡Supera os 9000!!!" + ], + "command": "git pull origin main:foo", + "beforeCommand": "git clone; git fakeTeamwork; go -b bar; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "OK: para rematar, alcanza o estado do obxectivo. Vase necesitar descargar algúns commits, crear algunhas ramas novas, e mesturar esas ramas xunto con outras, pero non debería levar demasiados domandos :P" + ] + } + } + ] + }, "zh_TW": { "childViews": [ { @@ -370,9 +526,9 @@ exports.level = { "如果我們在 fetch 的時候有指定`位置`的話,跟之前一樣,fetch 所做的事情沒有變,但是我們會 merge 我們剛剛所 fetch 的該`位置`的commit。" ], "afterMarkdowns": [ - "看吧!指定位置為 `master`,跟平常一樣,我們下載了 commit 並且放到 `o/master` 上,接著,我們會 merge `o/master` 到我們現在的位置,*不管*我們現在所 checkout 的位置在哪裡。" + "看吧!指定位置為 `main`,跟平常一樣,我們下載了 commit 並且放到 `o/main` 上,接著,我們會 merge `o/main` 到我們現在的位置,*不管*我們現在所 checkout 的位置在哪裡。" ], - "command": "git pull origin master", + "command": "git pull origin main", "beforeCommand": "git clone; go -b bar; git commit; git fakeTeamwork" } }, @@ -383,9 +539,9 @@ exports.level = { "他是不是也可以同時指定 source 以及 destination?你說對了啦!讓我們來看一下:" ], "afterMarkdowns": [ - "哇!這個指令強而有力,我們在 local 建立了一個新的 `foo` branch,下載了 remote 的 `master` 的 commit,並且放到 local 的 `foo` branch,之後 merge `foo` branch 到我們目前所 checkout 的 `bar` branch。這實在是太超過了!!!" + "哇!這個指令強而有力,我們在 local 建立了一個新的 `foo` branch,下載了 remote 的 `main` 的 commit,並且放到 local 的 `foo` branch,之後 merge `foo` branch 到我們目前所 checkout 的 `bar` branch。這實在是太超過了!!!" ], - "command": "git pull origin master:foo", + "command": "git pull origin main:foo", "beforeCommand": "git clone; git fakeTeamwork; go -b bar; git commit" } }, @@ -444,9 +600,9 @@ exports.level = { "如果我们指定要抓取的 place,所有的事情都会跟之前一样发生,只是增加了 merge 操作" ], "afterMarkdowns": [ - "看到了吧! 通过指定 `master` 我们更新了 `o/master`。然后将 `o/master` merge 到我们的检出位置,**无论**我们当前检出的位置是哪。" + "看到了吧! 通过指定 `main` 我们更新了 `o/main`。然后将 `o/main` merge 到我们的检出位置,**无论**我们当前检出的位置是哪。" ], - "command": "git pull origin master", + "command": "git pull origin main", "beforeCommand": "git clone; go -b bar; git commit; git fakeTeamwork" } }, @@ -457,9 +613,9 @@ exports.level = { "pull 也可以用 source:destination 吗? 当然喽, 看看吧:" ], "afterMarkdowns": [ - " 哇, 这个命令做的事情真多。它先在本地创建了一个叫 `foo` 的分支,从远程仓库中的 master 分支中下载提交记录,并合并到 `foo`,然后再 merge 到我们的当前检出的分支 `bar` 上。操作够多的吧?!" + " 哇, 这个命令做的事情真多。它先在本地创建了一个叫 `foo` 的分支,从远程仓库中的 main 分支中下载提交记录,并合并到 `foo`,然后再 merge 到我们的当前检出的分支 `bar` 上。操作够多的吧?!" ], - "command": "git pull origin master:foo", + "command": "git pull origin main:foo", "beforeCommand": "git clone; git fakeTeamwork; go -b bar; git commit" } }, @@ -483,7 +639,7 @@ exports.level = { "", "Da du jetzt so ziemlich *alles* kennst, was es an Optionen für `git fetch` und `git push` gibt, ist kaum noch etwas zu Optionen für `git pull` zu sagen. :)", "", - "Das liegt daran, dass `git pull` letztendlich *wirklich* nur eine Abkürzuung für `fetch` gefolgt von einem `merge` von was auch immer gerade heruntergeladen wurde, ist. Denk es dir als ein `git fetch` mit denselben Optionen und einem anschließenden Merge.", + "Das liegt daran, dass `git pull` letztendlich *wirklich* nur eine Abkürzuung für `fetch` gefolgt von einem `merge` von dem, was auch immer gerade heruntergeladen wurde, ist. Denk es dir als ein `git fetch` mit denselben Optionen und einem anschließenden Merge.", "", "Das trifft sogar zu, wenn du völlig abgedrehte Optionen verwendest. Ein paar Beispiele:" ] @@ -505,7 +661,7 @@ exports.level = { "", "`git fetch origin bar~1:bugFix; git merge bugFix`", "", - "Siehst du? `git pull` ist wirklich nur eine Abkürzung von `fetch` + `merge` und es interessiert sich nur dafür wo die Commits hin sollen (die \"Ziel\"-Option, die es beim `fetch` auswertet).", + "Siehst du? `git pull` ist wirklich nur eine Abkürzung von `fetch` + `merge` und es interessiert sich nur dafür, wo die Commits hin sollen (die \"Ziel\"-Option, die es beim `fetch` auswertet).", "", "Schauen wir uns eine Demonstration an:" ] @@ -515,12 +671,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Wenn wir den Ort, auf den das `fetch` ausgeführt werden soll, angeben, passiert alles so wie beim `git fetch` aber es wird direkt danach auch ein Merge ausgeführt." + "Wenn wir den Ort, auf den das `fetch` ausgeführt werden soll, angeben, passiert alles so wie beim `git fetch`, aber es wird direkt danach auch ein Merge ausgeführt." ], "afterMarkdowns": [ - "Siehst du? Da wir `master` angegeben haben sind die Commits in `o/master` heruntergeladen worden. Danach wurde `o/master` gemerged, egal was gerade ausgecheckt war." + "Siehst du? Da wir `main` angegeben haben, sind die Commits in `o/main` heruntergeladen worden. Danach wurde `o/main` gemerged, egal was gerade ausgecheckt war." ], - "command": "git pull origin master", + "command": "git pull origin main", "beforeCommand": "git clone; go -b bar; git commit; git fakeTeamwork" } }, @@ -531,9 +687,9 @@ exports.level = { "Funktioniert das auch wenn man Quelle und Ziel angibt? Aber sicher! Das sehen wir hier:" ], "afterMarkdowns": [ - "Wow, das ist eine Menge in einem einzelnen Befehl. Wir haben lokal einen neuen Branch namens `foo` erstellt, die Commits vom `master` des Servers dorthin heruntergeladen und ihn danach in unseren aktuell ausgecheckten Commit `bar` gemerged." + "Wow, das ist eine Menge in einem einzelnen Befehl. Wir haben lokal einen neuen Branch namens `foo` erstellt, die Commits vom `main` des Servers dorthin heruntergeladen und ihn danach in unseren aktuell ausgecheckten Branch `bar` gemerged." ], - "command": "git pull origin master:foo", + "command": "git pull origin main:foo", "beforeCommand": "git clone; git fakeTeamwork; go -b bar; git commit" } }, @@ -541,7 +697,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Ok, um's zu Ende zu bringen versuch das Ziel aus der Zielgrafik zu erreichen. Du wirst einige Commits herunterladen, einige neue Branches anlegen und diese in andere mergen müssen, aber das sollte nicht allzuviele Befehle benötigen. :P" + "Ok, um's zu Ende zu bringen versuch das Ziel aus der Zielgrafik zu erreichen. Du wirst einige Commits herunterladen, einige neue Branches anlegen und diese in andere mergen müssen, aber das sollte nicht allzu viele Befehle benötigen. :P" ] } } @@ -589,12 +745,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Здесь сначала выполнится fetch с аргументом указанным к pull, а merge выполняется с теми изменениями, которые будут скачаны командой fetch" + "Здесь сначала выполнится fetch с аргументом указанным к pull, а merge выполняется с теми изменениями, которые будут скачаны командой fetch." ], "afterMarkdowns": [ - "Как видно, мы указали `master`, поэтому как обычно все обновления притянулись на ветку `o/master`. Затем мы слили (merge) обновленную ветку `o/master` с веткой, на которой мы находимся." + "Как видно, мы указали `main`, поэтому как обычно все обновления притянулись на ветку `o/main`. Затем мы слили (merge) обновленную ветку `o/main` с веткой, на которой мы находимся." ], - "command": "git pull origin master", + "command": "git pull origin main", "beforeCommand": "git clone; go -b bar; git commit; git fakeTeamwork" } }, @@ -605,9 +761,9 @@ exports.level = { "Будет ли это работать, если указать `<источник>` и `<приемник>`? Проверим:" ], "afterMarkdowns": [ - "Ого, сколько всего выполнено всего одной командой!. Мы создали новую ветку `foo` в локальном репозитории, скачали на неё изменения с ветки `master` удаленного репозитория, а затем слили эту ветку с веткой `bar`, на которой мы находились!" + "Ого, сколько всего выполнено всего одной командой!. Мы создали новую ветку `foo` в локальном репозитории, скачали на неё изменения с ветки `main` удаленного репозитория, а затем слили эту ветку с веткой `bar`, на которой мы находились!" ], - "command": "git pull origin master:foo", + "command": "git pull origin main:foo", "beforeCommand": "git clone; git fakeTeamwork; go -b bar; git commit" } }, @@ -653,7 +809,7 @@ exports.level = { "", "`git fetch origin bar~1:bugFix; git merge bugFix`", "", - "보이죠? git pull은 그저 fetch + merge의 축양형일 뿐이에요, 그리고 git pull은 커밋들이 도착하는곳을 신경씁니다(fetch를 하며 지정된 `destination`인자의 위치로 merge가 수행됩니다).", + "보이죠? git pull은 그저 fetch + merge의 축약형일 뿐이에요, 그리고 git pull은 커밋들이 도착하는곳을 신경씁니다(fetch를 하며 지정된 `destination`인자의 위치로 merge가 수행됩니다).", "", "직접 확인해봅시다:" ] @@ -666,9 +822,9 @@ exports.level = { "place를 지정하면, 이전에 fecth를 하던때와 완전히 똑같이 진행되고 fetch한것을 병합합니다." ], "afterMarkdowns": [ - "보이죠! `master`를 지정해서 우리는 `o/master`에 평소처럼 커밋들을 내려받았습니다. 그다음 우리가 있는 곳으로 `o/master`를 병합했습니다 현재 체크아웃된 브랜치와 *상관없이* 말이죠" + "보이죠! `main`를 지정해서 우리는 `o/main`에 평소처럼 커밋들을 내려받았습니다. 그다음 우리가 있는 곳으로 `o/main`를 병합했습니다 현재 체크아웃된 브랜치와 *상관없이* 말이죠" ], - "command": "git pull origin master", + "command": "git pull origin main", "beforeCommand": "git clone; go -b bar; git commit; git fakeTeamwork" } }, @@ -681,7 +837,7 @@ exports.level = { "afterMarkdowns": [ "이야, 명령어 하나에 많은게 일어나고있습니다. 로컬에 이름이 `foo`인 새 브랜치를 만들고, 원격 저장소의 master에서 이 브랜치 `foo`에 커밋들을 내려받습니다, 그후 그 브랜치를 우리가 현재 체크아웃한 브랜치 `bar`로 병합했습니다. 오오오!!!" ], - "command": "git pull origin master:foo", + "command": "git pull origin main:foo", "beforeCommand": "git clone; git fakeTeamwork; go -b bar; git commit" } }, @@ -740,9 +896,9 @@ exports.level = { "Якщо ми вказуємо місце призначення для fetch, fetch виконується як звичайно, але мердж відбудеться з тим, що ми щойно стягнули" ], "afterMarkdowns": [ - "От бачиш, вказавши `master`, ми звантажили коміти в `o/master`, як завжди. Потім змерджили `o/master` в поточну гілку." + "От бачиш, вказавши `main`, ми звантажили коміти в `o/main`, як завжди. Потім змерджили `o/main` в поточну гілку." ], - "command": "git pull origin master", + "command": "git pull origin main", "beforeCommand": "git clone; go -b bar; git commit; git fakeTeamwork" } }, @@ -753,9 +909,9 @@ exports.level = { "Чи це працює також при вказанні `source` і `destination`? І не сумнівайся! Ось приклад:" ], "afterMarkdowns": [ - "Ого, стільки роботи однією командою. Ми створили локальну гілку з назвою `foo`, звантажили в неї коміти з віддаленого master, а потім змерджили `foo` в поточну гілку `bar`!" + "Ого, стільки роботи однією командою. Ми створили локальну гілку з назвою `foo`, звантажили в неї коміти з віддаленого main, а потім змерджили `foo` в поточну гілку `bar`!" ], - "command": "git pull origin master:foo", + "command": "git pull origin main:foo", "beforeCommand": "git clone; git fakeTeamwork; go -b bar; git commit" } }, @@ -768,6 +924,154 @@ exports.level = { } } ] + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Tham số git pull", + "", + "Giờ thì bạn đã biết gần như là *tất cả* về tham số của `git fetch` và `git push`, thế thì hầu như chẳng còn gì mới cho git pull cả :)", + "", + "Đó và vì nói cho cùng thì git pull *về thực tế* cũng chỉ là lệnh tắt cho tìm nạp và sau đó là hợp nhất những gì vừa mới được nạp. Bạn có thể coi nó như là chạy lệnh git fetch với *cùng* tham số được chỉ định và sau đó hợp nhất các commit vào *nơi* được chỉ định.", + "", + "Điều này được áp dụng kể cả khi bạn sử dụng những tham số phức tạp đến độ điên rồ. Hãy xem qua một vài ví dụ:" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Dưới đây là một vài câu lệnh tương đồng nhau trong git:", + "", + "`git pull origin foo` tương đương với:", + "", + "`git fetch origin foo; git merge o/foo`", + "", + "Và...", + "", + "`git pull origin bar~1:bugFix` tương đương với:", + "", + "`git fetch origin bar~1:bugFix; git merge bugFix`", + "", + "Thấy chứ? git pull thực ra chỉ là lệnh tắt cho fetch + merge, và tất cả những gì git pull quan tâm là nơi mà các commit sẽ tới (tham số `đích` mà nó diễn giải được trong quá trình nạp).", + "", + "Hãy xem qua một bản giới thiệu:" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Nếu ta chỉ định vị trí để nạp, mọi thứ diễn ra như với git fetch nhưng giờ đây có thêm một bước đó là ta hợp nhất những gì mà ta đã nạp" + ], + "afterMarkdowns": [ + "Thấy chứ! Bằng cách chỉ định nhánh `main` ta tải các commit xuống nhánh `o/main` như thường lệ. Sau đó hợp nhất nhánh `o/main` vào nhánh cục bộ mà ta đang đứng, nhánh mà *không phải* nhánh cục bộ `main`. Nhờ vậy mà ta có thể chạy cùng một lệnh git pull(với cùng tham số) nhiều lần ở những vị trí khác nhau để áp dụng cùng cập nhật lên các nhánh khác nhau." + ], + "command": "git pull origin main", + "beforeCommand": "git clone; go -b bar; git commit; git fakeTeamwork" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Điều này có hoạt động với đích và nguồn không? Đoán đúng rồi đấy! Cùng xem thử nào:" + ], + "afterMarkdowns": [ + "Wao, quá NHIỀU trong một câu lệnh. Ta tạo ra một nhánh cục bộ là `foo`, tải commit xuống từ nhánh từ xa main xuống nhánh `foo` đó, và sau đó hợp nhất commit vào nhánh `bar` mà ta đang đứng. Đủ thứ luôn!!!" + ], + "command": "git pull origin main:foo", + "beforeCommand": "git clone; git fakeTeamwork; go -b bar; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Được rồi, để kết thúc khóa học, hãy đạt đến mục tiêu được mô tả. Bạn sẽ cần tải xuống vài commit, tạo ra vài nhánh mới, và hợp nhất những nhánh đó sang những nhánh khác, nhưng mà đừng dùng nhiều lệnh quá nhé :P" + ] + } + } + ] + }, + "sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git pull argumenti", + "", + "Sedaj, ko veš praktično *vse*, kar je za vedeti o argumentih za `git fetch` in `git push`, ni skoraj ničesar za dodati za `git pull` :)", + "", + "To je zato, ker je git pull konec koncev *res* samo bližnjica za fetch, ki mu sledi merge tega, kar smo fetchali. Predstavljaš si ga lahko kot ukaz git fetch z *istimi* podanimi argumenti in merganjem, *kjer* bodo tisti commiti končali.", + "", + "To velja tudi takrat, ko uporabiš noro komplicirane argumente. Poglejmo nekaj primerov:" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Tu je nekaj ukazov v gitu:", + "", + "`git pull origin foo` je enak:", + "", + "`git fetch origin foo; git merge o/foo`", + "", + "In ...", + "", + "`git pull origin bar~1:bugFix` je enak:", + "", + "`git fetch origin bar~1:bugFix; git merge bugFix`", + "", + "Vidiš? Git pull je res bližnjica za fetch + merge. Vse kar zanima git pull je, kje bodo commiti končali (`ciljni` argument, ki ga ugotovi med fetchem).", + "", + "Poglejmo primer:" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Če določimo mesto za fetchanje, se zgodi vse kot prej s fetchem, ampak tudi zmergamo, kar smo pravkar fetchali." + ], + "afterMarkdowns": [ + "Vidiš! Z določitvijo `main` smo prenesli commite na `o/main` kot ponavadi. Potem smo zmergali `o/main` v našo trenutno checkoutano lokacijo, ki *ni* lokalni branch `main`. Zaradi tega razloga je morda celo logično, da izvedemo git pull večkrat (z istimi argumenti) iz drugi lokacij, da posodobimo več branchev." + ], + "command": "git pull origin main", + "beforeCommand": "git clone; go -b bar; git commit; git fakeTeamwork" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Ali deluje tudi z izvorom in ciljem? Itak! Poglejmo to:" + ], + "afterMarkdowns": [ + "Wow, to je pa RES veliko v enem ukazu. Naredili smo nov lokalen branch imenovan `foo`, prenesli commite iz oddaljenega masterja na ta branch `foo` in potem zmergali ta branch v naš trenutno checkoutan branch `bar`. Je več kot 9000!!!" + ], + "command": "git pull origin main:foo", + "beforeCommand": "git clone; git fakeTeamwork; go -b bar; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Ok, da zaključiš, pridi v stanje iz ciljne vizualizacije. Prenesti boš moral nekaj commitov, narediti nekaj novih branchev in zmergati te branche v druge branche, ampak ne bi smelo zahtevati veliko ukazov. :P" + ] + } + } + ] } } }; diff --git a/src/levels/remote/push.js b/src/levels/remote/push.js index 9d8591ab..fdbdffec 100644 --- a/src/levels/remote/push.js +++ b/src/levels/remote/push.js @@ -1,4 +1,7 @@ exports.level = { + "disabledMap": { + "git fakeTeamwork": true, + }, "goalTreeString": "{\"branches\":{\"master\":{\"target\":\"C3\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\",\"localBranchesThatTrackThis\":null},\"o/master\":{\"target\":\"C3\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":[\"master\"]}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C2\"],\"id\":\"C3\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C3\",\"id\":\"master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C2\"],\"id\":\"C3\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", "solutionCommand": "git commit;git commit;git push", "startTree": "{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\"},\"o/master\":{\"target\":\"C1\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"}},\"tags\":{},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"}},\"tags\":{},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", @@ -7,26 +10,33 @@ exports.level = { "zh_CN": "Git Push", "zh_TW": "git push", "es_AR": "git push", + "es_ES": "git push", "pt_BR": "Git Push", + "gl" : "Git Push", "de_DE": "Git Push", "ja" : "Git Push", "fr_FR": "Git push", "ru_RU": "Git push", "uk" : "Git push", - "ko" : "Git push" + "ko" : "Git push", + "vi" : "Git push", + "sl_SI": "Git Push" }, "hint": { "en_US": "Remember you have to clone before you can push!", "zh_CN": "推送之前需要先克隆", "zh_TW": "push 之前你需要先 clone", "es_AR": "¡Acordate que tenés que clonar antes de pushear!", + "es_ES": "¡Recuerda que tienes que clonar antes de hacer push!", "pt_BR": "Lembre-se de clonar antes de fazer o push!", "de_DE": "Denk dran, dass du einen Clone brauchst bevor du Pushen kannst!", "ja" : "Pushができるようになるには、まずリポジトリをcloneする必要があるのをお忘れなく", "fr_FR": "Rappelez-vous que vous devez cloner avant de pouvoir faire un push !", "ru_RU": "Помните, что прежде чем push-ить вам нужно склонировать репозиторий!", "uk" : "Пам’ятай, що перед тим як щось push-нути потрібно склонувати репозиторій!", - "ko" : "push를 하기전에 clone을 먼저해야 된다는것을 기억하세요!" + "ko" : "push를 하기전에 clone을 먼저해야 된다는것을 기억하세요!", + "vi" : "Nhớ rằng bạn phải clone trước khi push!", + "sl_SI": "Najprej moraš klonirati, preden lahko pushaš!" }, "startDialog": { "en_US": { @@ -56,7 +66,7 @@ exports.level = { "Here we have some changes that the remote does not have. Let's upload them!" ], "afterMarkdowns": [ - "There we go -- the remote received commit `C2`, the branch `master` on the remote was updated to point at `C2`, and our *own* reflection of the remote (`o/master`) was updated as well. Everything is in sync!" + "There we go -- the remote received commit `C2`, the branch `main` on the remote was updated to point at `C2`, and our *own* reflection of the remote (`o/main`) was updated as well. Everything is in sync!" ], "command": "git push", "beforeCommand": "git clone; git commit" @@ -99,7 +109,7 @@ exports.level = { "Nous avons fait ici quelques changements que le dépôt distant n'a pas. Envoyons-les !" ], "afterMarkdowns": [ - "Et voilà : le dépôt distant a reçu le commit `C2`, la branche `master` a été mise à jour sur `C2`, et votre *propre* représentation de la branche distante (`o/master`) a aussi été mise à jour. Tout est synchronisé !" + "Et voilà : le dépôt distant a reçu le commit `C2`, la branche `main` a été mise à jour sur `C2`, et votre *propre* représentation de la branche distante (`o/main`) a aussi été mise à jour. Tout est synchronisé !" ], "command": "git push", "beforeCommand": "git clone; git commit" @@ -140,7 +150,7 @@ exports.level = { "Acá tenemos algunos cambios que nuestro remoto no tiene. ¡Subámoslos!" ], "afterMarkdowns": [ - "Ahí está: el remoto recibió el commit `C2`, la rama `master` de ese remoto se actualizó para apuntar a `C2`, y nuestro *propio* reflejo del remoto (`o/master`) también fue actualizado. ¡Todo está en sincronía!" + "Ahí está: el remoto recibió el commit `C2`, la rama `main` de ese remoto se actualizó para apuntar a `C2`, y nuestro *propio* reflejo del remoto (`o/main`) también fue actualizado. ¡Todo está en sincronía!" ], "command": "git push", "beforeCommand": "git clone; git commit" @@ -156,6 +166,47 @@ exports.level = { } ] }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## git push", + "", + "Entendido, entonces ya descargué los cambios de un repositorio remoto y los integré en mi trabajo localmente. Esto suena muy bien... pero ¿cómo comparto _mis_ cambios con el resto?", + "", + "Bueno, la forma de subir el trabajo compartido es la opuesta a cómo descargar trabajo. Y ¿qué es lo opuesto a `git pull`? ¡`git push`!", + "", + "`git push` es el responsable de subir _tus_ cambios a un remoto específico y de actualizar ese remoto para incluir tus nuevos commits. Cuando `git push` termina, todos tus amigos pueden descargar tu trabajo del remoto.", + "", + "Puedes imaginarte `git push` como un comando para \"publicar\" tu trabajo. Tiene un par de sutilezas con las que vamos a meternos pronto, pero empecemos poco a poco." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Aquí tenemos algunos cambios que nuestro remoto no tiene. ¡Subámoslos!" + ], + "afterMarkdowns": [ + "Ahí está: el remoto recibió el commit `C2`, la rama `main` de ese remoto se actualizó para apuntar a `C2`, y nuestro *propio* reflejo del remoto (`o/main`) también fue actualizado. ¡Todo está en sincronía!" + ], + "command": "git push", + "beforeCommand": "git clone; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para completar este nivel, simplemente comparte dos nuevos commits con el remoto. Igualmente, no te confíes, ¡las lecciones van a empezar a complicarse!" + ] + } + } + ] + }, "pt_BR": { "childViews": [ { @@ -183,7 +234,7 @@ exports.level = { "Aqui temos algumas mudanças que o repositório remoto não contém. Vamos subi-las!" ], "afterMarkdowns": [ - "Aqui vamos nós -- o repositório remoto recebeu o commit `C2`, o ramo `master` no repositório remoto foi atualizado para apontar para `C2`, e a *nossa* reflexão do remoto (`o/master`) foi atualizada também. Está tudo sincronizado!" + "Aqui vamos nós -- o repositório remoto recebeu o commit `C2`, o ramo `main` no repositório remoto foi atualizado para apontar para `C2`, e a *nossa* reflexão do remoto (`o/main`) foi atualizada também. Está tudo sincronizado!" ], "command": "git push", "beforeCommand": "git clone; git commit" @@ -199,6 +250,49 @@ exports.level = { } ] }, + "gl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Push", + "", + "Ok, entón xa baixamos os cambios dun repositorio remoto e integrámolos na árbore local. Esto está xenial... pero ¿cómo comparto o _meu_ sensacional traballo cas outras persoas?", + "", + "Ben, a forma de subir traballo para ser compartido é a oposta daquela de baixar o traballo que foi compartido. E ¿qué é o oposto a `git pull` (tirar)? ¡É `git push` (empuxar)!", + "", + "`git push` é o responsable de subilos _teus_ cambios para un repositorio remoto especificado, e atualizar ese repositorio remoto para incorporar os seus novos commits. Unha vez que `git push` complétase, todos os teus amigos poderán baixar o teu traballo do repositorio remoto.", + "", + "Podes pensar en `git push` como un comando para \"publicar\" o teu traballo. O comando ten unha serie de detalles cos que imos xogar logo, pero comezemos con pasos curtos...", + "", + "*Nota -- o comportamento de `git push` sen argumentos varía dependendo da configuración `push.default` de Git. O valor para esa configuración depende da versión de Git que esteas empregando, pero imos asumir o valor `upstream` nestas leccións. Eso non é un gran problema, pero paga a pena verificalas súas configuracións antes de facer push nos teus propios proxectos.*" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Aquí temos algúns cambios que o repositorio remoto non contén. ¡Imos subilas!" + ], + "afterMarkdowns": [ + "Ahí imos -- o repositorio remoto recibiu o commit `C2`, a rama `main` do repositorio remoto foi actualizado para apuntar para `C2`, e o *noso* reflexo do remoto (`o/main`) foi atualizado tamén. ¡Está todo sincronizado!" + ], + "command": "git push", + "beforeCommand": "git clone; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para completar este nivel, comparte dous novos commits co repositorio remoto. Igual, non te confíes, ¡xa se complicará nas seguintes leccións!" + ] + } + } + ] + }, "zh_TW": { "childViews": [ { @@ -224,7 +318,7 @@ exports.level = { "這裡我們有了一些 remote 所沒有的 commit。讓我們來上傳它們吧!" ], "afterMarkdowns": [ - "我說的沒錯吧!remote 收到了 commit `C2`,同時在 remote 上的 `master` branch 也一起更新並且指向 `C2`,同時我們*自己的* `o/master` 也一併更新了!" + "我說的沒錯吧!remote 收到了 commit `C2`,同時在 remote 上的 `main` branch 也一起更新並且指向 `C2`,同時我們*自己的* `o/main` 也一併更新了!" ], "command": "git push", "beforeCommand": "git clone; git commit" @@ -268,7 +362,7 @@ exports.level = { "这里我们准备了一些远程仓库中没有的提交记录, 咱们开始先上传吧!" ], "afterMarkdowns": [ - "过去了, 远程仓库接收了 `C2`,远程仓库中的 `master` 分支也被更新到指向 `C2` 了,我们的远程分支 (o/master) 也同样被更新了。所有的分支都同步了!" + "过去了, 远程仓库接收了 `C2`,远程仓库中的 `main` 分支也被更新到指向 `C2` 了,我们的远程分支 (o/main) 也同样被更新了。所有的分支都同步了!" ], "command": "git push", "beforeCommand": "git clone; git commit" @@ -309,7 +403,7 @@ exports.level = { "Hier haben wir ein paar Änderungen, die auf dem Remote noch fehlen. Und hoch damit!" ], "afterMarkdowns": [ - "Na bitte -- das Remote hat den Commit `C2` bekommen, der `master` auf dem Remote ist entsprechend aktualisiert worden und unsere *eigene* Abbildung des `master` auf dem Remote namens `o/master` wurde auch aktualisiert. Alles im Lot!" + "Na bitte -- das Remote hat den Commit `C2` bekommen, der `main` auf dem Remote ist entsprechend aktualisiert worden und unsere *eigene* Abbildung des `main` auf dem Remote namens `o/main` wurde auch aktualisiert. Alles im Lot!" ], "command": "git push", "beforeCommand": "git clone; git commit" @@ -352,7 +446,7 @@ exports.level = { "Здесь у нас имеются изменения, которых нет в удалённом репозитории. Давайте же закачаем их туда!" ], "afterMarkdowns": [ - "Вот так - удалённый репозиторий получил новый коммит `C2`, ветка `master` на удалённом репозитории теперь указывает на `C2`, и наше *собственное* локальное отображение удалённого репозитория (`o/master`) изменилось соответственно. Всё синхронизировалось!" + "Вот так - удалённый репозиторий получил новый коммит `C2`, ветка `main` на удалённом репозитории теперь указывает на `C2`, и наше *собственное* локальное отображение удалённого репозитория (`o/main`) изменилось соответственно. Всё синхронизировалось!" ], "command": "git push", "beforeCommand": "git clone; git commit" @@ -395,7 +489,7 @@ exports.level = { "ここにリモートにはないいくつかの変更点があります。これをアップロードしてみましょう!" ], "afterMarkdowns": [ - "さて、いってみましょう -- リモートはコミット`C2`を受け取り、リモート上の`master`ブランチは`C2`の位置に更新され、私たち*自身*のリモートブランチ(`o/master`)も良い具合に更新されました。全てが同期されました!" + "さて、いってみましょう -- リモートはコミット`C2`を受け取り、リモート上の`main`ブランチは`C2`の位置に更新され、私たち*自身*のリモートブランチ(`o/main`)も良い具合に更新されました。全てが同期されました!" ], "command": "git push", "beforeCommand": "git clone; git commit" @@ -438,7 +532,7 @@ exports.level = { "Ось ми маємо деякі зміни яких нема в віддаленому сховищі. Надішлімо їх!" ], "afterMarkdowns": [ - "Ось, маєш -- віддалене сховище отримало `C2`, гілку `master` на ньому було оновлено й тепер вона посилається на `C2`, а наше *власне* відображення віддаленого репо (`o/master`) було також оновлено. Все синхронізовано!" + "Ось, маєш -- віддалене сховище отримало `C2`, гілку `main` на ньому було оновлено й тепер вона посилається на `C2`, а наше *власне* відображення віддаленого репо (`o/main`) було також оновлено. Все синхронізовано!" ], "command": "git push", "beforeCommand": "git clone; git commit" @@ -481,7 +575,7 @@ exports.level = { "여기 원격저장소에는 없는 변경이 있습니다. 이것들을 업로드 해 봅시다!" ], "afterMarkdowns": [ - "자 됬습니다 -- 원격 저장소가 커밋 `C2`를 받았고, 원격 저장소의 브랜치 `master`가 `C2`라는 지점까지 갱신 되었습니다. 그리고 원격 저장소의 반영인 *우리의* 원격 브랜치 (`o/master`)또한 잘 갱신 되었습니다. 모든게 동기화되어 있습니다!" + "자 됬습니다 -- 원격 저장소가 커밋 `C2`를 받았고, 원격 저장소의 브랜치 `main`가 `C2`라는 지점까지 갱신 되었습니다. 그리고 원격 저장소의 반영인 *우리의* 원격 브랜치 (`o/main`)또한 잘 갱신 되었습니다. 모든게 동기화되어 있습니다!" ], "command": "git push", "beforeCommand": "git clone; git commit" @@ -496,6 +590,92 @@ exports.level = { } } ] + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Push", + "", + "Được rồi, ta đã biết cách nạp thay đổi từ kho chứa từ xa và kết hợp chúng vào các nhánh cục bộ. Khá là tuyệt rồi... nhưng nếu tôi muốn chia sẻ tác phẩm tuyệt vời _của tôi_ với mọi người khác thì sao?", + "", + "Chà, cách tải lên thì phải ngược với tải xuống rồi. Vậy thì đối nghịch của `git pull`(kéo) là gì? `git push`(đẩy)!", + "", + "`git push` có trách nhiệm tải lên thay đổi _của bạn_ vào nhánh từ xa được chỉ định và cập nhật nhánh đó để kết hợp với commit đẩy lên của bạn. Một khi lệnh `git push` hoàn thành, tất cả bạn bè của bạn có thể tải xuống thay đổi của nhánh từ xa đó đó.", + "", + "Bạn có thể xem `git push` là câu lệnh để \"xuất bản\" thành quả công việc của bạn. Lệnh này có nhiều tính năng tinh tế mà ta sẽ tìm hiểu nhanh thôi, nhưng giờ hãy cứ bắt đầu với từng bước nhỏ đã...", + "", + "*lưu ý --`git push` mà không có tham số hành xử tùy biến phụ thuộc vào cài đặt của git là `push.default`. Giá trị mặc định cho cài đặt này phụ thuộc vào phiên bản git mà bạn đang sử dụng, còn ở bài học của chúng ta thì ta sẽ sử dụng giá trị `upstream` (ngược dòng). Bây giờ thì đó chưa phải là vấn đề gì lớn, nhưng chúng tôi khuyến nghị bạn kiểm tra cài đặt của mình trước khi đẩy lên dự án của bạn.*" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Ở đây ta có một vài thay đổi mà kho chứa từ xa không có. Hãy tải chúng lên!" + ], + "afterMarkdowns": [ + "Đó -- kho chứa từ xa đã nhận được commit `C2`, nhánh `main` ở kho chứa từ xa đã được cập nhật lên `C2`, và phản chiếu nhánh từ xa *của ta* (`o/main`) cũng được cập nhật luôn. Mọi thứ đã đồng bộ!" + ], + "command": "git push", + "beforeCommand": "git clone; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Để hoàn thành cấp độ này, đơn giản là hãy chia sẻ 2 commit mới với kho chứa từ xa. Chuẩn bị tinh thần nhé, vì các bài học sẽ khó dần lên nhiều đấy!" + ] + } + } + ] + }, + "sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Push", + "", + "Ok, sedaj sem fetchal spremembe iz oddaljenega repota in jih vključil v moje lokalno delo. To je že super ... toda kako delim _moje_ super delo z vsemi ostalimi?", + "", + "No, način da naložiš deljeno delo, je ravno nasproten, kot da ga preneseš. In kaj je nasprotje `git pull`? `git push`!", + "", + "`git push` je odgovoren za nalaganje _tvojih_ sprememb na določen oddaljen repozitorij in posodobitev tega repozitorija, da vključi tvoje nove commite. Ko se `git push` izvede, lahko vsi tvoji prijatelji prenesejo tvoje delo iz repozitorija.", + "", + "`git push` si lahko predstavljaš kot ukaz, ki \"objavi\" tvoje delo. Ima kopico majhnih stvari, katere bomo raziskali v kratkem, ampak začnimo z majhnimi koraki ...", + "", + "*Opomba -- obnašanje `git push` brez argumentov je odvisno od nastavitev gita imenovanih `push.default`. Privzeta vrednost za to nastavitev je odvisna od različice gita, ki jo uporabljaš, ampak mi bomo uporabljali `upstream` vrednost v naši lekciji. To ni neka velika stvar, ampak jo je vredno preveriti, preden pushamo na svojem projektu.*" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Tu imamo nekaj sprememb, ki jih oddaljen repo nima. Dajmo jih naložiti!" + ], + "afterMarkdowns": [ + "Tako je -- oddaljen repo je prejel commit `C2`, branch `main` na oddaljenem repotu je bil posodobljen, da kaže na `C2` in naš *lasten* prikaz oddaljenega repota (`o/main`) je bil prav tako posodobljen. Vse je usklajeno!" + ], + "command": "git push", + "beforeCommand": "git clone; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Za dokončanje te stopnje, preprosto deli dva nova commita z oddaljenim repotom. Nato pa se pripni, ker bodo lekcije postale dosti težje!" + ] + } + } + ] } } }; diff --git a/src/levels/remote/pushArgs.js b/src/levels/remote/pushArgs.js index 3b7f236c..19991785 100644 --- a/src/levels/remote/pushArgs.js +++ b/src/levels/remote/pushArgs.js @@ -1,6 +1,6 @@ exports.level = { "goalTreeString": "{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\"},\"foo\":{\"target\":\"C3\",\"id\":\"foo\",\"remoteTrackingBranchID\":\"o/foo\"},\"o/master\":{\"target\":\"C2\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null},\"o/foo\":{\"target\":\"C3\",\"id\":\"o/foo\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"}},\"HEAD\":{\"target\":\"C0\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\",\"remoteTrackingBranchID\":null},\"foo\":{\"target\":\"C3\",\"id\":\"foo\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", - "solutionCommand": "git push origin master;git push origin foo", + "solutionCommand": "git push origin main;git push origin foo", "startTree": "{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\"},\"foo\":{\"target\":\"C3\",\"id\":\"foo\",\"remoteTrackingBranchID\":\"o/foo\"},\"o/master\":{\"target\":\"C1\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null},\"o/foo\":{\"target\":\"C1\",\"id\":\"o/foo\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"}},\"HEAD\":{\"target\":\"C0\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\",\"remoteTrackingBranchID\":null},\"foo\":{\"target\":\"C1\",\"id\":\"foo\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", "disabledMap": { "git checkout": true @@ -10,26 +10,34 @@ exports.level = { "zh_CN": "Git push 的参数", "zh_TW": "git push 的參數", "es_AR": "Parámetros de git push", + "es_ES": "Parámetros de git push", "pt_BR": "Parâmetros do git push", + "gl" : "Parámetros de git push", "de_DE": "Optionen für Git Push", "ja" : "Git pushの引数", "fr_FR": "Arguments de git push", "ru_RU": "Аргументы git push", "ko" : "git push의 인자들", - "uk" : "Аргументи git push" + "uk" : "Аргументи git push", + "vi" : "Tham số git push", + "sl_SI": "Git push argumenti" }, "hint": { "en_US": "You can always look at the last slide of the dialog with \"objective\"", "zh_CN": "你可以利用“objective”来阅读对话窗口的最后一页", "zh_TW": "你可以利用 \"objective\" 來閱讀對話視窗的最後一頁", "es_AR": "Siempre podés ver el último mensaje tipeando \"objective\"", + "es_ES": "Siempre puedes ver el último mensaje escribiendo \"objective\"", "pt_BR": "Você sempre pode rever o último slide com o comando \"objective\"", + "gl" : "Ti sempre podes desfacer último mensaxe escribindo \"objective\"", "de_DE": "Du kannst dir die Zielsetzung des Levels immer wieder mit \"objective\" anzeigen lassen", "ja" : "ダイアログの最後のスライドを参照するには\"objective\"を実行", "fr_FR": "Vous pouvez toujours regarder le dernier slide des dialogues en tapant \"objective\".", "ru_RU": "Вы всегда можете ознакомиться с последним слайдом, воспользовавшись \"objective\".", "ko" : "대화창의 마지막 슬라이드를 \"objective\"로 다시 볼 수 있습니다.", - "uk" : "Завжди можна подивитися останній слайд діалогу за допомогою \"objective\"" + "uk" : "Завжди можна подивитися останній слайд діалогу за допомогою \"objective\"", + "vi" : "Bạn có thể sử dụng \"objective\" để đọc trang cuối của cửa sổ hộp thoại", + "sl_SI": "Vedno lahko pogledaš zadnji dialog z \"objective\"." }, "startDialog": { "en_US": { @@ -56,13 +64,13 @@ exports.level = { "markdowns": [ "What is a `` parameter you say? We'll dive into the specifics soon, but first an example. Issuing the command:", "", - "`git push origin master`", + "`git push origin main`", "", "translates to this in English:", "", - "*Go to the branch named \"master\" in my repository, grab all the commits, and then go to the branch \"master\" on the remote named \"origin.\" Place whatever commits are missing on that branch and then tell me when you're done.*", + "*Go to the branch named \"main\" in my repository, grab all the commits, and then go to the branch \"main\" on the remote named \"origin\". Place whatever commits are missing on that branch and then tell me when you're done.*", "", - "By specifying `master` as the \"place\" argument, we told git where the commits will *come from* and where the commits *will go*. It's essentially the \"place\" or \"location\" to synchronize between the two repositories.", + "By specifying `main` as the \"place\" argument, we told git where the commits will *come from* and where the commits *will go*. It's essentially the \"place\" or \"location\" to synchronize between the two repositories.", "", "Keep in mind that since we told git everything it needs to know (by specifying both arguments), it totally ignores where we are checked out!" ] @@ -75,9 +83,9 @@ exports.level = { "Let's see an example of specifying the arguments. Note the location where we are checked out in this example." ], "afterMarkdowns": [ - "There we go! `master` got updated on the remote since we specified those arguments." + "There we go! `main` got updated on the remote since we specified those arguments." ], - "command": "git checkout C0; git push origin master", + "command": "git checkout C0; git push origin main", "beforeCommand": "git clone; git commit" } }, @@ -98,7 +106,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Ok, for this level let's update both `foo` and `master` on the remote. The twist is that `git checkout` is disabled for this level!", + "Ok, for this level let's update both `foo` and `main` on the remote. The twist is that `git checkout` is disabled for this level!", "", "*Note: The remote branches are labeled with `o/` prefixes because the full `origin/` label does not fit in our UI. Don't worry ", "about this... simply use `origin` as the name of the remote like normal.*" @@ -131,13 +139,13 @@ exports.level = { "markdowns": [ "Qu'est ce que ce paramètre `` ? Avant de passer à l'explication, voyons d'abord un exemple. La commande suivante :", "", - "`git push origin master`", + "`git push origin main`", "", "peut se traduire en français par :", "", - "*Va dans la branche \"master\" de mon dépôt, récupère tous les commits, et ensuite va dans la branche distante \"master\" sur le dépôt nommé \"origin\". Envoie tous les commits qui lui manquent sur cette branche distante puis préviens-moi quand c'est terminé.*", + "*Va dans la branche \"main\" de mon dépôt, récupère tous les commits, et ensuite va dans la branche distante \"main\" sur le dépôt nommé \"origin\". Envoie tous les commits qui lui manquent sur cette branche distante puis préviens-moi quand c'est terminé.*", "", - "En spécifiant `master` comme argument ``, nous avons dit à git *d'où* les commits venaient et où ils *allaient*. C'est en fait \"l'emplacement\" à synchroniser entre les deux dépôts.", + "En spécifiant `main` comme argument ``, nous avons dit à git *d'où* les commits venaient et où ils *allaient*. C'est en fait \"l'emplacement\" à synchroniser entre les deux dépôts.", "", "Gardez à l'esprit que nous avons dit à git tout ce dont il a besoin pour opérer (en précisant les deux arguments), il n'a donc absolument pas besoin de savoir quelle est la branche courante !" ] @@ -150,9 +158,9 @@ exports.level = { "Voyons un exemple d'arguments. Notez bien où se trouve `HEAD` dans cet exemple." ], "afterMarkdowns": [ - "Voilà ! `master` a été mise à jour puisque nous avons spécifié ces arguments." + "Voilà ! `main` a été mise à jour puisque nous avons spécifié ces arguments." ], - "command": "git checkout C0; git push origin master", + "command": "git checkout C0; git push origin main", "beforeCommand": "git clone; git commit" } }, @@ -173,7 +181,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Ok, pour ce niveau mettez à jour `foo` et `master` sur le dépôt distant. La difficulté est que `git checkout` est désactivée pour ce niveau !" + "Ok, pour ce niveau mettez à jour `foo` et `main` sur le dépôt distant. La difficulté est que `git checkout` est désactivée pour ce niveau !" ] } } @@ -187,7 +195,7 @@ exports.level = { "markdowns": [ "## Parámetros de push", "", - "¡Genial! Ahora que sabés acerca de las ramas que trackean remotos podemos empezar a develar algo del misterio detrás de git push, fetch y pull. Vamos a atacar de a un comando a la vez, pero los conceptos entre ellos son muy similares.", + "¡Genial! Ahora que sabés acerca de las ramas que trackean remotos podemos empezar a desvelar algo del misterio detrás de git push, fetch y pull. Vamos a atacar de a un comando a la vez, pero los conceptos entre ellos son muy similares.", "", "Veamos primero `git push`. Ya aprendiste en la lección sobre ramas remotas que git determinó el remoto *y* la rama a la que pushear mirando las propiedades de la rama actual (el remoto al que \"trackea\"). Este es el comportamiento default para cuando no se especifican parámetros, pero git push toma, opcionalmente, parámetros de la forma:", "", @@ -203,13 +211,13 @@ exports.level = { "markdowns": [ "¿Qué será este parámetro ``, te preguntarás? Ya vamos a entrar en detalle, pero primero un ejemplo. Correr el comando:", "", - "`git push origin master`", + "`git push origin main`", "", "se traduce así al español:", "", - "*Andá a la rama llamada \"master\" en mi repositorio, agarrá todos los commits, y después andá a la rama \"master\" del remoto llamado \"origin\". Aplicá ahí todos los commits que falten, y avisame cuando termines.*", + "*Andá a la rama llamada \"main\" en mi repositorio, agarrá todos los commits, y después andá a la rama \"main\" del remoto llamado \"origin\". Aplicá ahí todos los commits que falten, y avisame cuando termines.*", "", - "Especificando `master` como el parámetro \"lugar\", le dijimos a git de dónde traer los commits, y a dónde mandarlos. Es, básicamente, el \"lugar\" o \"ubicación\" que sincronizar entre ambos repositorios.", + "Especificando `main` como el parámetro \"lugar\", le dijimos a git de dónde traer los commits, y a dónde mandarlos. Es, básicamente, el \"lugar\" o \"ubicación\" que sincronizar entre ambos repositorios.", "", "Tené en cuenta que, como le dijimos a git todo lo que necesitaba saber (especificando ambos parámetros), ¡ignora totalmente dónde estamos parados en este momento¡" ] @@ -222,9 +230,9 @@ exports.level = { "Veamos un ejemplo especificando los parámetros. Notá en dónde estamos parados en este ejemplo." ], "afterMarkdowns": [ - "¡Ahí está! Se actualizó `master` en el remoto, porque especificamos esos parámetros." + "¡Ahí está! Se actualizó `main` en el remoto, porque especificamos esos parámetros." ], - "command": "git checkout C0; git push origin master", + "command": "git checkout C0; git push origin main", "beforeCommand": "git clone; git commit" } }, @@ -245,7 +253,79 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Ok. Para este nivel, actualicemos tanto `foo` como `master` en el remoto. El tema está en que ¡tenemos deshabilitado `git checkout` en este nivel!" + "Ok. Para este nivel, actualicemos tanto `foo` como `main` en el remoto. El tema está en que ¡tenemos deshabilitado `git checkout` en este nivel!" + ] + } + } + ] + }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Parámetros de push", + "", + "¡Genial! Ahora que has aprendido sobre las ramas que trackean remotos podemos empezar a desvelar algo del misterio detrás de git push, fetch y pull. Vamos a atacar un comando cada vez, pero los conceptos entre ellos son muy similares.", + "", + "Veamos primero `git push`. Ya aprendiste en la lección sobre ramas remotas que git determinó el remoto *y* la rama a la que pushear mirando las propiedades de la rama actual (el remoto al que \"trackea\"). Este es el comportamiento por defecto para cuando no se especifican parámetros, pero git push toma, opcionalmente, parámetros de la forma:", + "", + "`git push `", + "", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "¿Qué será este parámetro ``, te preguntarás? Vamos a entrar en detalle, pero primero un ejemplo. Ejecutar el comando:", + "", + "`git push origin main`", + "", + "se traduce así al español:", + "", + "*Vete a la rama llamada \"main\" en mi repositorio, coge todos los commits, y después vete a la rama \"main\" del remoto llamado \"origin\". Copia ahí todos los commits que falten, y avísame cuando termines.*", + "", + "Especificando `main` como el parámetro \"lugar\", le dijimos a git de dónde traer los commits, y a dónde mandarlos. Es, básicamente, el \"lugar\" o \"ubicación\" que sincronizar entre ambos repositorios.", + "", + "Ten en cuenta que, como le dijimos a git todo lo que necesitaba saber (especificando ambos parámetros), ¡ignora totalmente dónde estamos parados en este momento¡" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Veamos un ejemplo especificando los parámetros. Date cuenta dónde estamos parados en este ejemplo." + ], + "afterMarkdowns": [ + "¡Ahí está! Se actualizó `main` en el remoto, porque especificamos esos parámetros." + ], + "command": "git checkout C0; git push origin main", + "beforeCommand": "git clone; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "¿Y si no especificabamos los parámetros? ¿Qué hubiera pasado?" + ], + "afterMarkdowns": [ + "El comando falla (como puedes ver), porque `HEAD` no está sobre ninguna rama que apunte a algún remoto." + ], + "command": "git checkout C0; git push", + "beforeCommand": "git clone; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Perfecto. Para este nivel, actualicemos tanto `foo` como `main` en el remoto. El tema está en que ¡tenemos deshabilitado `git checkout` en este nivel!" ] } } @@ -275,13 +355,13 @@ exports.level = { "markdowns": [ "Você deve estar se perguntando: o que é esse parâmetro ``? Vamos discutir as especifidades em breve, mas vejamos primeiro um exemplo. Executar o comando:", "", - "`git push origin master`", + "`git push origin main`", "", "pode ser traduzido para o seguinte em Português:", "", - "*Vá ao ramo chamado \"master\" no meu repositório local, pegue todos os commits, então vá ao ramo \"master\" no repositório remoto chamado \"origin\". Coloque quaisquer commits que estiverem faltando nesse ramo, e então me diga quando estiver pronto.*", + "*Vá ao ramo chamado \"main\" no meu repositório local, pegue todos os commits, então vá ao ramo \"main\" no repositório remoto chamado \"origin\". Coloque quaisquer commits que estiverem faltando nesse ramo, e então me diga quando estiver pronto.*", "", - "Especificando `master` como parâmetro \"lugar\", dizemos ao Git de onde os commits *vão vir* e para onde os commits *irão*. É essencialmente o \"lugar\" onde sincronizar entre os dois repositórios.", + "Especificando `main` como parâmetro \"lugar\", dizemos ao Git de onde os commits *vão vir* e para onde os commits *irão*. É essencialmente o \"lugar\" onde sincronizar entre os dois repositórios.", "", "Tenha em mente que já que contamos ao Git tudo que ele precisa saber (especificando ambos os parâmetros), ele ignora totalmente o checkout atual!" ] @@ -294,9 +374,9 @@ exports.level = { "Vejamos um exemplo especificando os argumentos. Preste atenção no commit que sofreu checkout neste exemplo." ], "afterMarkdowns": [ - "Aqui vamos nós! O `master` foi atualizado no repositório remoto, já que especificamos os parâmetros." + "Aqui vamos nós! O `main` foi atualizado no repositório remoto, já que especificamos os parâmetros." ], - "command": "git checkout C0; git push origin master", + "command": "git checkout C0; git push origin main", "beforeCommand": "git clone; git commit" } }, @@ -317,7 +397,79 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Ok, neste nível vamos atualizar tanto o `foo` como o `master` no repositório remoto. Porém desabilitamos o comando `git checkout` para dificultar um pouco a tarefa!" + "Ok, neste nível vamos atualizar tanto o `foo` como o `main` no repositório remoto. Porém desabilitamos o comando `git checkout` para dificultar um pouco a tarefa!" + ] + } + } + ] + }, + "gl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Parámetros de push", + "", + "¡Xenial! Agora que sabes acerca das ramas que seguen remotos, podemos empezas a desvelar algo do misterio detrás do git push, fetch e pull. Imos atacar cun só comando dunha vez, pero os conceptos entre eles son moi semellantes.", + "", + "Vexamos primeiro `git push`. Xa aprendiches na lección sobre as ramas remotas que git determina o remoto *e* a rama á que empurrar mirando as propiedades da rama actual (o remoto ó que seguir). Este é o comportamento por defecto para cando non se especifican parámetros, pero git push toma, opcionalmente, parámetros da forma:", + "", + "`git push `", + "", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "¿Qué será este parámetro ``, fixécheste esa pregunta? Xa imos entrar en detalle, pero primeiro un exemplo. Executa o comando:", + "", + "`git push origin main`", + "", + "tradúcese así ó galego:", + "", + "*Vai á rama chamada \"main\" no meu repositorio, colle tódolos commits, e despois vai á rama \"main\" do remoto chamado \"origin\". Aplica ahí tódolos commits que falten, e avísame cando remates.*", + "", + "Indicando `main` como o parámetro \"lugar\", dixémoslle a git ónde traer os commits, e ónde mandalos. É básicamente, o \"lugar\" ou \"ubicación\" que sincroniza entre ámbolos dous repositorios.", + "", + "Ten en conta que, como lle dixemos a git todo o que precisaba saber (indicando ambos parámetros), ¡ignora totalmente ónde andabamos neste momento!" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Vexamos un exemplo especificando os parámetros. Nota ónde ficamos parados neste exemplo." + ], + "afterMarkdowns": [ + "¡Ahí o tes! Actualizouse `main` no remoto, porque especificamos eses parámetros." + ], + "command": "git checkout C0; git push origin main", + "beforeCommand": "git clone; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "¿E se non especificáramos os parámetros? ¿Que ocorrería?" + ], + "afterMarkdowns": [ + "O comando falla (como podes ver), xa que `HEAD` non está sobre ningunha rama que siga algún remoto." + ], + "command": "git checkout C0; git push", + "beforeCommand": "git clone; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Ok. Para este nivel, actualiza tanto `foo` como `main` no remoto. O tema está en que ¡temos deshabilitado `git checkout` neste nivel!" ] } } @@ -347,13 +499,13 @@ exports.level = { "markdowns": [ "`` 這個參數表示什麼? 我們等一下會提到細節,但是先來看一個例子,執行以下的指令:", "", - "`git push origin master`", + "`git push origin main`", "", "將這段解釋成中文:", "", - "*先到我的 repo 中的 \"master\" branch,抓下所有的 commit,然後到叫作 \"origin\" 的 remote 的 \"master\" branch,檢查 remote 的 commit 有沒有跟我的 repo 一致,如果沒有,就更新。*", + "*先到我的 repo 中的 \"main\" branch,抓下所有的 commit,然後到叫作 \"origin\" 的 remote 的 \"main\" branch,檢查 remote 的 commit 有沒有跟我的 repo 一致,如果沒有,就更新。*", "", - "將 `master` 當作 \"place\" 這個參數,我們告訴 git 這些 commit 是*從哪裡來的*,而且它們要*往哪裡去*。對於要同步兩個 repo, \"place\" 或者是 \"location\" 是非常重要的。", + "將 `main` 當作 \"place\" 這個參數,我們告訴 git 這些 commit 是*從哪裡來的*,而且它們要*往哪裡去*。對於要同步兩個 repo, \"place\" 或者是 \"location\" 是非常重要的。", "", "要記住喔,因為我們告訴 git 它所要知道的(有兩個參數),因此它才不會管你現在所 checkout 的 branch!" ] @@ -366,9 +518,9 @@ exports.level = { "讓我們來看一個有加上參數的例子,在這個例子中,要特別注意到我們所 checkout 的位置。" ], "afterMarkdowns": [ - "我說的沒錯吧!因為我們加上了參數,所以在 remote 上的 `master` branch 更新了。" + "我說的沒錯吧!因為我們加上了參數,所以在 remote 上的 `main` branch 更新了。" ], - "command": "git checkout C0; git push origin master", + "command": "git checkout C0; git push origin main", "beforeCommand": "git clone; git commit" } }, @@ -389,7 +541,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "好的,在這個關卡中,我們要更新在 remote 上的 `foo` 以及 `master` branch,比較遺憾的是 `git checkout` 在這個關卡中是不被允許的喔!" + "好的,在這個關卡中,我們要更新在 remote 上的 `foo` 以及 `main` branch,比較遺憾的是 `git checkout` 在這個關卡中是不被允許的喔!" ] } } @@ -419,13 +571,13 @@ exports.level = { "markdowns": [ "`` 参数是什么意思呢?我们稍后会深入其中的细节, 先看看例子, 这个命令是:", "", - "`git push origin master`", + "`git push origin main`", "", "把这个命令翻译过来就是:", "", - "*切到本地仓库中的“master”分支,获取所有的提交,再到远程仓库“origin”中找到“master”分支,将远程仓库中没有的提交记录都添加上去,搞定之后告诉我。*", + "*切到本地仓库中的“main”分支,获取所有的提交,再到远程仓库“origin”中找到“main”分支,将远程仓库中没有的提交记录都添加上去,搞定之后告诉我。*", "", - "我们通过“place”参数来告诉 Git 提交记录来自于 master, 要推送到远程仓库中的 master。它实际就是要同步的两个仓库的位置。", + "我们通过“place”参数来告诉 Git 提交记录来自于 main, 要推送到远程仓库中的 main。它实际就是要同步的两个仓库的位置。", "", "需要注意的是,因为我们通过指定参数告诉了 Git 所有它需要的信息, 所以它就忽略了我们所检出的分支的属性!" ] @@ -438,9 +590,9 @@ exports.level = { "我们看看指定参数的例子。注意下我们当前检出的位置。" ], "afterMarkdowns": [ - "好了! 通过指定参数, 远程仓库中的 `master` 分支得到了更新。" + "好了! 通过指定参数, 远程仓库中的 `main` 分支得到了更新。" ], - "command": "git checkout C0; git push origin master", + "command": "git checkout C0; git push origin main", "beforeCommand": "git clone; git commit" } }, @@ -461,7 +613,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "本关我们要更新远程仓库中的 `foo` 和 `master`, 但是 `git checkout` 被禁用了!", + "本关我们要更新远程仓库中的 `foo` 和 `main`, 但是 `git checkout` 被禁用了!", "", "*注意:远程分支使用 `o/` 开头是因为 `origin/` 对于 UI 来说太长了。不用太在意这个,直接用 `origin` 作为远程仓库的名称就可以了。*", "" @@ -478,7 +630,7 @@ exports.level = { "markdowns": [ "## Push-Optionen", "", - "Großartig! Da du dich jetzt mit Remote Tracking Branches auskennst können wir anfangen, die Geheimnisse hinter `git push`, `fetch` und `pull` zu ergründen. Wir werden uns einen Befehl nach dem anderen vornehmen, aber die Funktionsweisen sind sich sehr ähnlich.", + "Großartig! Da du dich jetzt mit Remote Tracking Branches auskennst, können wir anfangen, die Geheimnisse hinter `git push`, `fetch` und `pull` zu ergründen. Wir werden uns einen Befehl nach dem anderen vornehmen, aber die Funktionsweisen sind sich sehr ähnlich.", "", "Zunächst schauen wir uns `git push` an. Du hast im Level über Remote Tracking schon mitbekommen, dass Git den Remote Server *und* den Branch herausbekommt, indem es sich die Eigenschaften des aktuell ausgecheckten Branches ansieht (in denen das Remote steht, das der Branch \"trackt\"). Das ist das Verhalten bei keiner Angabe weiterer Optionen -- du kannst bei `git push` aber auch folgende setzen:", "", @@ -492,17 +644,17 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Was \"Ort\" sein soll fragst du? Das klären wir später genau, schauen wir uns zunächst ein Beispiel an:", + "Was \"Ort\" sein soll, fragst du? Das klären wir später genau, schauen wir uns zunächst ein Beispiel an:", "", - "`git push origin master`", + "`git push origin main`", "", "Das bedeutet im Klartext:", "", - "\"Geh zum Branch namens `master` in meinem Repository, nimm all seine Commits, dann geh zum Branch `master` auf dem Remote namens `origin`. Leg da alles Commits ab die fehlen und sag mir wenn du fertig bist.\"", + "\"Geh zum Branch namens `main` in meinem Repository, nimm all seine Commits, dann geh zum Branch `main` auf dem Remote namens `origin`. Lege da alle Commits ab, die fehlen und sage mir, wenn du fertig bist.\"", "", - "Dadurch, dass wir `master` als \"Ort\" angegeben haben, weiß Git *woher* die Commits kommen und *wohin* sie sollen. Es ist im Grunde der Name der Orte, die zwischen zwei Repositorys synchronisiert werden soll.", + "Da wir `main` als \"Ort\" angegeben haben, weiß Git, *woher* die Commits kommen und *wohin* sie sollen. Es ist im Grunde der Name der Orte, die zwischen zwei Repositorys synchronisiert werden sollen.", "", - "Dadurch, dass wir Git alles explizit gesagt haben, was es für die Operation wissen muss (durch Angabe von Remote und Ort) ist es vollkommen egal, was gerade ausgecheckt ist." + "Da wir Git alles explizit gesagt haben, was es für die Operation wissen muss (durch Angabe von Remote und Ort), ist es vollkommen egal, was gerade ausgecheckt ist." ] } }, @@ -510,12 +662,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Schauen wir uns noch ein Beispiel an. Beachte was in diesem Fall gerade ausgecheckt ist." + "Schauen wir uns noch ein Beispiel an. Beachte, was in diesem Fall gerade ausgecheckt ist." ], "afterMarkdowns": [ - "Da haben wir's! `master` wurde auf dem Remote aktualisiert, weil wir beide Optionen angegeben haben." + "Da haben wir's! `main` wurde auf dem Remote aktualisiert, weil wir beide Optionen angegeben haben." ], - "command": "git checkout C0; git push origin master", + "command": "git checkout C0; git push origin main", "beforeCommand": "git clone; git commit" } }, @@ -536,7 +688,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Ok, in diesem Level lass und sowohl `foo` als auch `master` auf dem Remote aktualisieren. Um's spannender zu machen, ist `git checkout` in diesem Level deaktiviert." + "Ok, in diesem Level lass uns sowohl `foo` als auch `main` auf dem Remote aktualisieren. Um's spannender zu machen ist `git checkout` in diesem Level deaktiviert." ] } } @@ -566,13 +718,13 @@ exports.level = { "markdowns": [ "Что за такой параметр `<целевая_ветка>`? Мы узнаем об этом через секунду, а пока что рассмотрим пример. Допустим, что мы выполняем такую команду:", "", - "`git push origin master`", + "`git push origin main`", "", "дословный перевод с английского будет таким:", "", - "*Перейди в ветку с именем \"master\" в моём локальном репозитории, возьми все коммиты и затем перейди на ветку \"master\" на удалённом репозитории \"origin.\". На эту удалённую ветку скопируй все отсутствующие коммиты, которые есть у меня, и скажи, когда ты закончишь.*", + "*Перейди в ветку с именем \"main\" в моём локальном репозитории, возьми все коммиты и затем перейди на ветку \"main\" на удалённом репозитории \"origin.\". На эту удалённую ветку скопируй все отсутствующие коммиты, которые есть у меня, и скажи, когда ты закончишь.*", "", - "Указывая `master` в качестве аргумента \"целевая_ветка\", мы тем самым говорим git-у откуда будут *приходить* и *уходить* наши коммиты. Аргумент \"целевая_ветка\" или \"местонахождение\" - это синхронизация между двумя репозиториями.", + "Указывая `main` в качестве аргумента \"целевая_ветка\", мы тем самым говорим git-у откуда будут *приходить* и *уходить* наши коммиты. Аргумент \"целевая_ветка\" или \"местонахождение\" - это синхронизация между двумя репозиториями.", "", "Имейте в виду, что с тех пор, как мы сказали git-у всё, что ему необходимо (указав оба аргумента), ему - git-у - абсолютно всё равно, что вы зачекаутили до этого!" ] @@ -585,9 +737,9 @@ exports.level = { "Давайте взглянем на пример, в котором указаны оба этих аргумента. Обратите внимание на местоположение, в котором мы находимся после чекаута." ], "afterMarkdowns": [ - "Вот так! Мы обновили `master` на удалённом репозитории, принудительно указав аргументы в push." + "Вот так! Мы обновили `main` на удалённом репозитории, принудительно указав аргументы в push." ], - "command": "git checkout C0; git push origin master", + "command": "git checkout C0; git push origin main", "beforeCommand": "git clone; git commit" } }, @@ -608,7 +760,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Хорошо, для выполнения этого уровня давайте обновим обе ветки `foo` и `master` на удалённом репозитории. Фишка в том, что команда `git checkout` не доступна на этом уровне!", + "Хорошо, для выполнения этого уровня давайте обновим обе ветки `foo` и `main` на удалённом репозитории. Фишка в том, что команда `git checkout` не доступна на этом уровне!", "", "*Замечание: Удалённые ветки помечены как `o/`, а не `origin/`. Дело в том, что полная метка не помещается на экране. Не волнуйтесь ", "по этому поводу... просто используйте знакомый нам `origin` для обращения к удалённому репозиторию.*" @@ -641,13 +793,13 @@ exports.level = { "markdowns": [ "``인자가 무엇을 의미할것 같나요? 세부사항은 알아보기 전에 예시부터 봅시다. 다음 명령어를 보세요:", "", - "`git push origin master`", + "`git push origin main`", "", "해석해 보면:", "", - "*내 저장소에 있는 \"master\"라는 이름의 브랜치로 가서 모든 커밋들을 수집합니다, 그다음 \"origin\"의 \"master\"브랜치로 가서 이 브랜치에 부족한 커밋들을 채워 넣고 완료 되면 알려줍니다.*", + "*내 저장소에 있는 \"main\"라는 이름의 브랜치로 가서 모든 커밋들을 수집합니다, 그다음 \"origin\"의 \"main\"브랜치로 가서 이 브랜치에 부족한 커밋들을 채워 넣고 완료 되면 알려줍니다.*", "", - "`master`를 \"place\"인자로 지정해서 우리가 git에게 *어디서부터* 커밋이 오는지, 그리고 *어디로* 커밋이 가야하는지 알려줍니다. 두 저장소간에 동기화 작업을 할 \"장소\"를 지정해 주는것이라고 볼 수 있습니다.", + "`main`를 \"place\"인자로 지정해서 우리가 git에게 *어디서부터* 커밋이 오는지, 그리고 *어디로* 커밋이 가야하는지 알려줍니다. 두 저장소간에 동기화 작업을 할 \"장소\"를 지정해 주는것이라고 볼 수 있습니다.", "", "git이 알아야 할 것은 다 알려줬기 때문에(두 인자를 모두 지정했죠), git은 현재 우리가 체크아웃한 브랜치는 무시하고 명령을 수행합니다." ] @@ -660,9 +812,9 @@ exports.level = { "인자를 지정해주는 예제를 눈으로 직접 확인해 봅시다. 이 예제에서 우리가 체크아웃한 곳이 어디인지를 주의하며 봅시다." ], "afterMarkdowns": [ - "됬네요! 지정해준 인자들에 의해 원격 저장소의 `master`가 갱신 되었습니다." + "됬네요! 지정해준 인자들에 의해 원격 저장소의 `main`가 갱신 되었습니다." ], - "command": "git checkout C0; git push origin master", + "command": "git checkout C0; git push origin main", "beforeCommand": "git clone; git commit" } }, @@ -683,7 +835,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "좋습니다, 이번 레벨에서는 원격저장소의 `foo`, `master`브랜치 모두 갱신해봅시다. 이번 문제는 `git checkout`이 비활성화 되있다는 점이 특징이죠!", + "좋습니다, 이번 레벨에서는 원격저장소의 `foo`, `main`브랜치 모두 갱신해봅시다. 이번 문제는 `git checkout`이 비활성화 되있다는 점이 특징이죠!", "", "*노트: 원격 브랜치들은 `o/`접두어로 분류되어 있습니다. `origin/`으로 생략없이 표현하면 UI에 안맞아서 이렇게 표현했어요. ", "그래서... 원격저장소 이름은 원래처럼 `origin`으로 써주세요.*" @@ -716,13 +868,13 @@ exports.level = { "markdowns": [ "Ви спитаєте, що таке аргумент ``? Ми скоро вдамося в детальні пояснення, але спочатку -- приклад. Виконання команди:", "", - "`git push origin master`", + "`git push origin main`", "", "буквально перекладається як:", "", - "*Піди в гілку, що називається \"master\" в моєму репозиторії, візьми всі коміти, піди у віддалений \"master\", що називається \"origin\". Додай ті коміти, яких немає в цій гілці і надрукуй, що саме ти зробив.*", + "*Піди в гілку, що називається \"main\" в моєму репозиторії, візьми всі коміти, піди у віддалений \"main\", що називається \"origin\". Додай ті коміти, яких немає в цій гілці і надрукуй, що саме ти зробив.*", "", - "Вказуючи `master` в якості аргумента \"place\", ми сказали git-у, *звідки* взяти коміти і *куди* їх додати. (\"Place\") - фактично точка синхронізації двох репозиторіїв.", + "Вказуючи `main` в якості аргумента \"place\", ми сказали git-у, *звідки* взяти коміти і *куди* їх додати. (\"Place\") - фактично точка синхронізації двох репозиторіїв.", "", "Пам'ятайте, що оскільки ми надали git-у всю необхідну інформацію (вказавши обидва аргументи), не має значення яка гілка є зараз поточною!" ] @@ -735,9 +887,9 @@ exports.level = { "Розгляньмо приклад використання аргументів. Зверніть увагу на поточну гілку в цьому прикладі." ], "afterMarkdowns": [ - "Ось так! `master` у віддаленому репозиторії оновився, оскільки ми вказали його в аргументах." + "Ось так! `main` у віддаленому репозиторії оновився, оскільки ми вказали його в аргументах." ], - "command": "git checkout C0; git push origin master", + "command": "git checkout C0; git push origin main", "beforeCommand": "git clone; git commit" } }, @@ -758,7 +910,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Гаразд, на цьому рівні оновімо віддалені гілки `foo` і `master`. Для ускладнення ми заборонимо використовувати `git checkout`!", + "Гаразд, на цьому рівні оновімо віддалені гілки `foo` і `main`. Для ускладнення ми заборонимо використовувати `git checkout`!", "", "*Пам'ятай, віддалені гілки позначені префіксом `o/`, оскільки повний префікс `origin/` не влазить в наш UI. Але не хвилюйся ", "про це... ти можеш використовувати `origin` посилаючись на віддалений репозиторій.*" @@ -766,6 +918,156 @@ exports.level = { } } ] + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Tham số đẩy", + "", + "Tuyệt! Bạn đã biết đến theo dõi từ xa, giờ thì ta có thể tìm hiểu sâu hơn về cách hoạt động của đẩy( `git push`), tìm nạp(`git fetch`) và kéo(`git pull`). Ta sẽ giải quyết từng câu lệnh một nhưng về căn bản chúng khá là giống nhau.", + "", + "Trước hết hãy xem qua `git push`. Trong bài học về theo dõi từ xa bạn đã biết rằng git sử dụng thuộc tính(nhánh từ xa mà nó \"theo dõi\") của nhánh hiện tại để xác định kho và nhánh từ xa để đẩy. Git làm việc này mà không cần tham số chỉ định, nhưng lệnh git push có thể thêm tham số dưới dạng sau:", + "", + "`git push `", + "", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Tham số `` là gì vậy? Chúng ta sẽ đi sâu vào chi tiết sau sau, hãy xem ví dụ trước. Đưa ra câu lệnh:", + "", + "`git push origin main`", + "", + "được dịch lại là:", + "", + "*Chuyển sang nhánh \"main\" trong kho lưu trữ cục bộ, nhận tất cả các commit và tìm nhánh \"main\" trong kho chứa từ xa tên là \"origin\". Thêm tất cả các commit không có trong nhánh đó và báo cho tôi biết khi nào hoàn tất.*", + "", + "Bằng cách chỉ định `main` trong tham số \"vị trí\",ta báo với git nơi mà commit *xuất phát* và nơi chúng *sẽ đến*. Về căn bản nó là \"địa điểm\" để đồng bộ hóa 2 kho chứa.", + "", + "Lưu ý rằng ta ta đã thông báo cho gi tất cả thông tin cần thiết( thông qua chỉ định 2 tham số), nó sẽ không quan tâm nhánh mà ta đang đứng!" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Hãy xem xét một ví dụ về việc xác định tham số. Lưu ý vị trí nhánh mà ta đang đứng." + ], + "afterMarkdowns": [ + "Được rồi! Bằng cách chỉ định các tham số, nhánh `main` trong kho lưu trữ từ xa đã được cập nhật." + ], + "command": "git checkout C0; git push origin main", + "beforeCommand": "git clone; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Giả sử ta không chỉ định các tham số thì sao? Điều gì sẽ xảy ra?" + ], + "afterMarkdowns": [ + "Lệnh thất bại (như bạn có thể thấy, không có gì xảy ra)! Bởi vì `HEAD` không trỏ đến nhánh nào có theo dõi từ xa." + ], + "command": "git checkout C0; git push", + "beforeCommand": "git clone; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Được rồi, trong cấp độ này hãy cập nhánh `foo` và `main` trên kho lưu trữ từ xa. Cái khó là ở cấp độ này lệnh `git checkout` đã bị vô hiệu hóa!", + "", + "*Chú ý: Các nhánh từ xa được đánh dấu bằng tiền tố `o/` bời vì UI của chúng tôi không chứa được hết `origin/`. Đừng lo ", + "về vấn đề này... đơn giản cứ dùng `origin` như bình thường thôi.*" + ] + } + } + ] + }, + "sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Push argumenti", + "", + "Super! Sedaj, ko poznaš oddaljeno sledenje branchev lahko začnemo odkrivati skrivnosti za git pushem, fetchem in pullom. Napadli bomo en ukaz za drugim, ampak koncepti za njimi so si podobni.", + "", + "Najprej bomo pogledali `git push`. V lekciji o oddaljenem sledenju si spoznal, da je git ugotovil oddaljen repo *in* branch za pushat s tem da je pogledal lastnosti trenutno checkoutanega brancha (oddaljen branch, ki ga \"sledi\"). To je obnašanje brez argumentov, ampak git push lahko sprejme tudi argumente v sledeči obliki:", + "", + "`git push `", + "", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Kaj je `` parameter praviš? Kmalu bomo zaplavali v podrobnosti, ampak najprej primer. Izvedba ukaza:", + "", + "`git push origin main`", + "", + "se v slovenščini prevede v:", + "", + "*Pojdi na branch poimenovan \"main\" na mojem repozitoriju, zgrabi vse commite in nato pojdi na branch \"main\" na oddaljenem repotu poimenovanem \"origin\". Postavi vse commite, ki manjkajo na branch in me obvesti, ko končaš.*", + "", + "Z določanjem `masterja` kot \"place\" argument, smo povedali gitu iz kje bodo commiti *prišli* in kam bodo commiti *šli*. V bistvu je to \"mesto\" oziroma \"lokacija\" za uskladitev med dvema repozitorijema.", + "", + "Imej v mislih, da ker smo gitu povedali vse kar mora vedeti (s podajanjem obeh argumentov), git povsem ignorira mesto, kjer smo checkoutani!" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Poglejmo si primer podajanja argumentov. Bodi pozoren na mesto, kjer smo checkoutani v tem primeru." + ], + "afterMarkdowns": [ + "Evo ga! `main` je bil posodobljen na oddaljenem repotu, ker smo podali te argumente." + ], + "command": "git checkout C0; git push origin main", + "beforeCommand": "git clone; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Kaj če ne bi podali argumentov? Kaj bi se zgodilo?" + ], + "afterMarkdowns": [ + "Ukaz ne uspe (kot lahko vidiš), ker `HEAD` ni checkoutan na branchu, ki ga oddaljeno sledimo." + ], + "command": "git checkout C0; git push", + "beforeCommand": "git clone; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Ok, za to stopnjo posodobimo oba `foo` in `main` na oddaljenem repotu. Trik je, da je `git checkout` onemogočen za to stopnjo!", + "", + "*Opomba: Oddaljeni branchi so označeni z `o/` predpono, ker celotna `origin/` oznaka ne paše v naš prikaz. Ne skrbi ", + "glede tega ... preprosto uporabi `origin` kot ime oddaljenega repota kot ponavadi.*" + ] + } + } + ] } } }; diff --git a/src/levels/remote/pushArgs2.js b/src/levels/remote/pushArgs2.js index d9804f94..61dc1047 100644 --- a/src/levels/remote/pushArgs2.js +++ b/src/levels/remote/pushArgs2.js @@ -1,32 +1,40 @@ exports.level = { "goalTreeString": "{\"branches\":{\"master\":{\"target\":\"C6\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\"},\"foo\":{\"target\":\"C4\",\"id\":\"foo\",\"remoteTrackingBranchID\":\"o/foo\"},\"o/master\":{\"target\":\"C4\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null},\"o/foo\":{\"target\":\"C5\",\"id\":\"o/foo\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C2\",\"C3\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C2\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C5\"],\"id\":\"C6\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C4\",\"id\":\"master\",\"remoteTrackingBranchID\":null},\"foo\":{\"target\":\"C5\",\"id\":\"foo\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C5\":{\"parents\":[\"C2\"],\"id\":\"C5\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C2\",\"C3\"],\"id\":\"C4\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", - "solutionCommand": "git push origin master^:foo;git push origin foo:master", + "solutionCommand": "git push origin main^:foo;git push origin foo:main", "startTree": "{\"branches\":{\"master\":{\"target\":\"C6\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\"},\"foo\":{\"target\":\"C4\",\"id\":\"foo\",\"remoteTrackingBranchID\":\"o/foo\"},\"o/master\":{\"target\":\"C1\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null},\"o/foo\":{\"target\":\"C1\",\"id\":\"o/foo\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C2\",\"C3\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C2\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C5\"],\"id\":\"C6\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\",\"remoteTrackingBranchID\":null},\"foo\":{\"target\":\"C1\",\"id\":\"foo\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", "name": { "en_US": "Git push arguments -- Expanded!", "zh_CN": "Git push 参数 2", "zh_TW": "git push 的參數,延伸討論!", "es_AR": "¡Más! Parámetros de git push", + "es_ES": "¡Más! Parámetros de git push", "pt_BR": "Parâmetros do git push -- expandido", + "gl" : "Parámetros de git push -- ampliado", "de_DE": "Optionen für Git Push -- noch mehr!", "ja" : "Git pushの引数 -- 拡張編!", "fr_FR": "Arguments de git push -- toujours plus !", "ru_RU": "Аргументы для push -- расширенная версия!", "ko" : "git push 인자 -- 확장판!", - "uk" : "Розширені аргументи git push!" + "uk" : "Розширені аргументи git push!", + "vi" : "Tham số git push -- bản mở rộng!", + "sl_SI": "Git push argumenti -- Razširjeni!" }, "hint": { "en_US": "Remember you can admit defeat and type in \"show solution\" :P", "zh_CN": "如果你认输的话,可以通过“show solution”查看解决方案 :P", "zh_TW": "如果你失敗了,可以利用 \"show solution\" 來找到解答:P", "es_AR": "Recordá que podés admitir tu derrota y tipear \"show solution\" para ver la solución :P", + "es_ES": "Recuerda que puedes admitir tu derrota y escribir \"show solution\" para ver la solución :P", "pt_BR": "Lembre-se que você pode admitir que foi derrotado e digitar \"show solution\" :P", + "gl" : "Lembrate que podes admitir que fuches derrotado e escribir \"show solution\" para amosala solución :P", "de_DE": "Vergiss nicht dass du aufgeben kannst, indem du \"show solution\" eingibst :P", "ja" : "降参して解説を見るには\"show solution\"を実行できるのをお忘れなく", "fr_FR": "N'oubliez pas que vous pouvez toujours déclarer forfait avec \"show solution\" :P", "ru_RU": "Помните, Вы всегда можете признать своё поражение, набрав команду \"show solution\" (показать решение) :P", "ko" : "혹시 아세요? 패배를 인정하고 \"show solution\"을 입력할 수 있다는 걸요 :P", - "uk" : "Пам'ятай, ти завжди можеш визнати поразку і підглянути рішення командою \"show solution\" :P" + "uk" : "Пам'ятай, ти завжди можеш визнати поразку і підглянути рішення командою \"show solution\" :P", + "vi" : "Nhớ rằng, bạn có thể thừa nhận thất bại và gõ \"show solution\" :P", + "sl_SI": "Vedno se lahko predaš in napišeš \"show solution\". :P" }, "startDialog": { "en_US": { @@ -37,7 +45,7 @@ exports.level = { "markdowns": [ "## `` argument details", "", - "Remember from the previous lesson that when we specified `master` as the place argument for git push, we specified both the *source* of where the commits would come from and the *destination* of where the commits would go.", + "Remember from the previous lesson that when we specified `main` as the place argument for git push, we specified both the *source* of where the commits would come from and the *destination* of where the commits would go.", "", "You might then be wondering -- what if we wanted the source and destination to be different? What if you wanted to push commits from the `foo` branch locally onto the `bar` branch on remote?", "", @@ -55,7 +63,7 @@ exports.level = { "", "`git push origin :`", "", - "This is commonly referred to as a colon refspec. Refspec is just a fancy name for a location that git can figure out (like the branch `foo` or even just `HEAD~1`)", + "This is commonly referred to as a colon refspec. Refspec is just a fancy name for a location that git can figure out (like the branch `foo` or even just `HEAD~1`).", "", "Once you are specifying both the source and destination independently, you can get quite fancy and precise with remote commands. Let's see a demo!" ] @@ -70,7 +78,7 @@ exports.level = { "afterMarkdowns": [ "Woah! That's a pretty trippy command but it makes sense -- git resolved `foo^` into a location, uploaded whatever commits that weren't present yet on the remote, and then updated destination." ], - "command": "git push origin foo^:master", + "command": "git push origin foo^:main", "beforeCommand": "git clone; go -b foo; git commit; git commit" } }, @@ -83,7 +91,7 @@ exports.level = { "afterMarkdowns": [ "Sweet, that's pretty slick :D" ], - "command": "git push origin master:newBranch", + "command": "git push origin main:newBranch", "beforeCommand": "git clone; git commit" } }, @@ -107,7 +115,7 @@ exports.level = { "markdowns": [ "## L'argument `` dans le détail", "", - "Rappelez-vous de notre dernière leçon : quand vous passiez `master` comme argument `` à git push, cela spécifiait à la fois la *source* de provenance des commits et leur *destination*.", + "Rappelez-vous de notre dernière leçon : quand vous passiez `main` comme argument `` à git push, cela spécifiait à la fois la *source* de provenance des commits et leur *destination*.", "", "Vous vous demandez peut-être donc : et si nous voulions avoir une source et une destination différentes ? Et si vous voulez envoyez des commits de la branche locale `foo` dans la branche distante `bar` ?", "", @@ -140,7 +148,7 @@ exports.level = { "afterMarkdowns": [ "Woahou ! C'est une commande très alambiquée mais qui a du sens : git résoud `foo^` en un emplacement, envoie tous les commits qui n'étaient pas encore présents sur le dépôt distant, et met ensuite à jour la branche de destination." ], - "command": "git push origin foo^:master", + "command": "git push origin foo^:main", "beforeCommand": "git clone; go -b foo; git commit; git commit" } }, @@ -153,7 +161,7 @@ exports.level = { "afterMarkdowns": [ "Cool, c'est habile :D" ], - "command": "git push origin master:newBranch", + "command": "git push origin main:newBranch", "beforeCommand": "git clone; git commit" } }, @@ -177,11 +185,11 @@ exports.level = { "markdowns": [ "## Detalles sobre el parámetro ``", "", - "Acordate de la lección anterior que cuando especificamos `master` como el parámetro lugar de git push, especificamos tanto el *origen* del que sacar los commits como el *destino* al que enviarlos.", + "Acordate de la lección anterior que cuando especificamos `main` como el parámetro lugar de git push, especificamos tanto el *origen* del que sacar los commits como el *destino* al que enviarlos.", "", - "Podrías estár preguntándote ¿Y si quisieramos que el origen y el destino sean distintos? ¿Si quisieras pushear los commits de la rama local `foo` a la rama `bar` del remote?", + "Podrías estar preguntándote ¿Y si quisiéramos que el origen y el destino sean distintos? ¿Si quisieras pushear los commits de la rama local `foo` a la rama `bar` del remote?", "", - "Bueno, lamentablemente eso no se puede hacer en git... ¡Bazinga! Claro que se puede :)... git es extremadísimamente flexible (casi casi que demsiado).", + "Bueno, lamentablemente eso no se puede hacer en git... ¡Bazinga! Claro que se puede :)... git es extremadísimamente flexible (casi casi que demasiado).", "", "Veamos cómo hacerlo a continuación..." ] @@ -197,7 +205,7 @@ exports.level = { "", "Esto se lo suele llamar refspec con dos puntos. Refspec es simplemente un nombre cool para una ubicación que git puede entender (como la rama `foo`, o incluso `HEAD~1`)", "", - "Una vez que especificás tanto el origen como el destino independientemente, podés ponerte bastante cómodo y preciso con los comandos remotos. ¡Veámos una demo!" + "Una vez que especificás tanto el origen como el destino independientemente, podés ponerte bastante cómodo y preciso con los comandos remotos. ¡Veamos una demo!" ] } }, @@ -210,7 +218,7 @@ exports.level = { "afterMarkdowns": [ "¡Woow! Ese commando es bastante loco, pero tiene sentido: git resolvió `foo^` a una ubicación, subió cualquier commit de ahí que aún no estuviera en el remoto, y luego actualizó el destino." ], - "command": "git push origin foo^:master", + "command": "git push origin foo^:main", "beforeCommand": "git clone; go -b foo; git commit; git commit" } }, @@ -218,12 +226,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "¿Y qué hay si el destino que al querés pushear no existe? ¡No hay drama! Simplemente dale un nombre al branch y git se va a encargar de creártelo en el remoto." + "¿Y qué hay si el destino al que querés pushear no existe? ¡No hay drama! Simplemente dale un nombre al branch y git se va a encargar de creártelo en el remoto." ], "afterMarkdowns": [ "Genial, simplemente fluye :D" ], - "command": "git push origin master:newBranch", + "command": "git push origin main:newBranch", "beforeCommand": "git clone; git commit" } }, @@ -239,6 +247,76 @@ exports.level = { } ] }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Detalles sobre el parámetro ``", + "", + "Recuerda de la lección anterior que cuando especificamos `main` como el parámetro lugar de git push, especificamos tanto el *origen* del que sacar los commits como el *destino* al que enviarlos.", + "", + "Podrías estar preguntándote ¿Y si quisiéramos que el origen y el destino fuesen distintos? ¿Si quisieras hacer push de los commits de la rama local `foo` a la rama `bar` del remote?", + "", + "Bueno, lamentablemente eso no se puede hacer en git... ¡zasca! Claro que se puede :)... git es extremadamente flexible (casi casi que demasiado).", + "", + "Veamos cómo hacerlo a continuación..." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para especificar tanto el origen como el destino de ``, simplemente únelos usando el signo `dos puntos`:", + "", + "`git push origin :`", + "", + "A esto se le suele llamar refspec con dos puntos. Refspec es simplemente un nombre genial para una ubicación que git puede entender (como la rama `foo`, o incluso `HEAD~1`)", + "", + "Una vez que especificas tanto el origen como el destino independientemente, puedes ponerte bastante cómodo y preciso con los comandos remotos. ¡Veamos una demo!" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Recuerda: `origen` es cualquier ubicación que git pueda entender:" + ], + "afterMarkdowns": [ + "¡Vaya! Ese commando es bastante rompedor, pero tiene sentido: git resolvió `foo^` a una ubicación, subió cualquier commit de ahí que aún no estuviera en el remoto, y luego actualizó el destino." + ], + "command": "git push origin foo^:main", + "beforeCommand": "git clone; go -b foo; git commit; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "¿Y qué ocurre si el destino al que quieres hacer push no existe? ¡Sin problema! Simplemente dale un nombre a la rama y git se va a encargar de creártelo en el remoto." + ], + "afterMarkdowns": [ + "Genial, simplemente fluye :D" + ], + "command": "git push origin main:newBranch", + "beforeCommand": "git clone; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para este nivel, trata de llegar al objetivo final, y recuerda el formato:", + "", + "`:`" + ] + } + } + ] + }, "pt_BR": { "childViews": [ { @@ -247,7 +325,7 @@ exports.level = { "markdowns": [ "## Detalhes sobre ``", "", - "Lembra que na lição anterior especificamos `master` como o parâmetro lugar para o git push? Lá definimos tanto a *origem* de onde os commits viriam quanto o *destino* para onde os commits foram.", + "Lembra que na lição anterior especificamos `main` como o parâmetro lugar para o git push? Lá definimos tanto a *origem* de onde os commits viriam quanto o *destino* para onde os commits foram.", "", "Você pode estar se perguntando -- e se eu quisesse que a origem e o destino fossem diferentes? E se eu quisesse enviar commits do ramo local `foo` para o ramo remoto `bar`?", "", @@ -280,7 +358,7 @@ exports.level = { "afterMarkdowns": [ "Uau! Esse comando é bastante viajado, mas ele faz sentido -- o Git entendeu a referência `foo^`, enviou quaisquer commits que não estavam presentes no repositório remoto, e então atualizou o destino." ], - "command": "git push origin foo^:master", + "command": "git push origin foo^:main", "beforeCommand": "git clone; go -b foo; git commit; git commit" } }, @@ -293,7 +371,7 @@ exports.level = { "afterMarkdowns": [ "Doce, isso é muito bom :D" ], - "command": "git push origin master:newBranch", + "command": "git push origin main:newBranch", "beforeCommand": "git clone; git commit" } }, @@ -309,6 +387,76 @@ exports.level = { } ] }, + "gl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Detalles sobre o parámetro ``", + "", + "Lémbrate da lección anterior cando especificamos `main` como o parámetro lugar de git push, especificamos tanto a *orixe* do que sacar os commits como o *destino* ó que envialos.", + "", + "Poderías estar a preguntarte ¿E se quixéramos que a orixe e o destino sexan distintos? ¿Se quixéramos empurrar os commits da rama local `foo` á rama `bar` do remoto?", + "", + "Bueno, esto non se pode facer en git... ¡Caramboliñas! Claro que se pode :D. git é extremadísimamente flexibe (case case que de máis).", + "", + "Vexamos cómo facelo a continuación..." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para especificar tanto a orixe como o destino de ``, sinxelamente úneos empregando dous puntos:", + "", + "`git push origin :`", + "", + "Esto pódeselle chamar refspec con dous puntos. Refspec é sinxelamente un nome cool para unha ubicación que git pode entender (como a rama `foo`, ou incluso `HEAD~1`)", + "", + "Unha vez que especificas a orixe e o destino independientemente, podes poñerte cómodo e preciso cos comandos remotos. ¡Vexamos a demo!" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Lembra: `orixe` é calquera ubicación que git poida entender:" + ], + "afterMarkdowns": [ + "¡Woow! Ese commando é unha tolemia, pero ten sentido: git resolveu `foo^` a unha ubicación, subiu calquera commit de ahí que aún non estivera no remoto, e logo actualizou o destino." + ], + "command": "git push origin foo^:main", + "beforeCommand": "git clone; go -b foo; git commit; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "¿E qué hai se o destino ó que queres empurrar non existise? ¡Non pasa nada! Sinxelamente dalle un nome á rama e git vaise encargar de crealo no remoto." + ], + "afterMarkdowns": [ + "Xenial, sinxelamente tira para adiante." + ], + "command": "git push origin main:newBranch", + "beforeCommand": "git clone; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para este nivel, intenta chegar o obxectivo final, e lembrate do formato:", + "", + "`:`" + ] + } + } + ] + }, "zh_TW": { "childViews": [ { @@ -317,7 +465,7 @@ exports.level = { "markdowns": [ "## `` 這個參數的細節", "", - "回想一下,我們在之前的課程中提到,當我們用 `git push` 並且把 `master` 當作 `` 這個參數的時候,我們就相當於告訴 git 我們的所要更新的 commit 要*從哪裡來*(source) 並且要 *往哪裡去*(destination)。", + "回想一下,我們在之前的課程中提到,當我們用 `git push` 並且把 `main` 當作 `` 這個參數的時候,我們就相當於告訴 git 我們的所要更新的 commit 要*從哪裡來*(source) 並且要 *往哪裡去*(destination)。", "", "你可能會很好奇,當我們的 source 以及 destination 是不同的時候,應該怎麼做?當你想要 push `foo` branch 上面的 commit 到 remote 的 `bar` branch 的時候,應該怎麼做?", "", @@ -348,9 +496,9 @@ exports.level = { "記住, `source` 表示任意可以被 git 辨識的位置:" ], "afterMarkdowns": [ - "哇!這實在是一個很花俏的指令但是確很合理,git 把 `foo^` 解讀成一個位置,並且 push 該位置的 commit 到目前 remote 的 master branch。" + "哇!這實在是一個很花俏的指令但是確很合理,git 把 `foo^` 解讀成一個位置,並且 push 該位置的 commit 到目前 remote 的 main branch。" ], - "command": "git push origin foo^:master", + "command": "git push origin foo^:main", "beforeCommand": "git clone; go -b foo; git commit; git commit" } }, @@ -363,7 +511,7 @@ exports.level = { "afterMarkdowns": [ "太讚了,實在非常地簡單:D" ], - "command": "git push origin master:newBranch", + "command": "git push origin main:newBranch", "beforeCommand": "git clone; git commit" } }, @@ -387,7 +535,7 @@ exports.level = { "markdowns": [ "## ``参数详解", "", - "还记得之前课程说的吧,当为 git push 指定 place 参数为 `master` 时,我们同时指定了提交记录的来源和去向。", + "还记得之前课程说的吧,当为 git push 指定 place 参数为 `main` 时,我们同时指定了提交记录的来源和去向。", "", "你可能想问 —— 如果来源和去向分支的名称不同呢?比如你想把本地的 `foo` 分支推送到远程仓库中的 `bar` 分支。", "", @@ -418,9 +566,9 @@ exports.level = { "记住,`source` 可以是任何 Git 能识别的位置:" ], "afterMarkdowns": [ - "这是个另人困惑的命令,但是它确实是可以运行的 —— Git 将 `foo^` 解析为一个位置,上传所有未被包含到远程仓库里 `master` 分支中的提交记录。" + "这是个另人困惑的命令,但是它确实是可以运行的 —— Git 将 `foo^` 解析为一个位置,上传所有未被包含到远程仓库里 `main` 分支中的提交记录。" ], - "command": "git push origin foo^:master", + "command": "git push origin foo^:main", "beforeCommand": "git clone; go -b foo; git commit; git commit" } }, @@ -433,7 +581,7 @@ exports.level = { "afterMarkdowns": [ "很赞吧!它是不是很聪明?! :D" ], - "command": "git push origin master:newBranch", + "command": "git push origin main:newBranch", "beforeCommand": "git clone; git commit" } }, @@ -457,11 +605,11 @@ exports.level = { "markdowns": [ "## Details zum ``-Parameter", "", - "Du erinnerst dich von dem vorherigen Level, dass, als wir `master` als \"Ort\" beim `git push` angegeben haben, daraus sowohl die *Quelle* als auch das *Ziel* für die Operation abgeleitet wurden.", + "Du erinnerst dich von dem vorherigen Level, dass, als wir `main` als \"Ort\" beim `git push` angegeben haben, daraus sowohl die *Quelle* als auch das *Ziel* für die Operation abgeleitet wurden.", "", - "Daher fragst du dich vielleicht -- was wenn wir möchten, dass Quelle und Ziel anders sind? Was wenn du Commits von einem lokalen Branch `foo` in den Branch `bar` auf einem Server schieben möchtest?", + "Daher fragst du dich vielleicht -- was wenn wir möchten, dass Quelle und Ziel verschieden voneinander sind? Was wenn du Commits von einem lokalen Branch `foo` in den Branch `bar` auf einem Server schieben möchtest?", "", - "Tja, leider ist das in Git unmöglich .... ein Scherz! Natürlich ist das möglich. Git besitzt tonnenweise Flexibilität (eher zuviel, als zuwenig).", + "Tja, leider ist das in Git unmöglich .... ein Scherz! Natürlich ist das möglich. Git besitzt tonnenweise Flexibilität (eher zu viel, als zu wenig).", "", "Und gleich sehen wir, wie das geht ..." ] @@ -475,9 +623,9 @@ exports.level = { "", "`git push origin :`", "", - "Das wird üblicherweise Refspec (Referenz-Spezifikation) genannt. Refspec ist nur ein anderer Name für einen Ort, mit dem Git etwas anfangen kann (wie mit Branch `foo` oder mit `HEAD~2`)", + "Das wird üblicherweise Refspec (Referenz-Spezifikation) genannt. Refspec ist nur ein anderer Name für einen Ort, mit dem Git etwas anfangen kann (wie mit Branch `foo` oder mit `HEAD~2`).", "", - "Sobald du Quelle und Ziel separat angibt, kannst du flexibel und präzise entfernte Branches ansteuern. Hier eine Demo:" + "Sobald du Quelle und Ziel separat angibst, kannst du flexibel und präzise entfernte Branches ansteuern. Hier eine Demo:" ] } }, @@ -488,9 +636,9 @@ exports.level = { "Vergiss nicht, `Quelle` ist jeder mögliche Ort, mit dem Git etwas anfangen kann:" ], "afterMarkdowns": [ - "Boah! Das ist ein ziemlich abgefahrener Befehl gewesen, aber er ist sinnvoll -- Git hat `foo^` zu einem Commit aufgelöst, alle Commits die bis zu diesem einschließich noch nicht auf dem Server waren hochgeladen und dann dort das Ziel aktualisiert." + "Boah! Das ist ein ziemlich abgefahrener Befehl gewesen, aber er ist sinnvoll -- Git hat `foo^` zu einem Commit aufgelöst, alle Commits, die bis zu einschließlich diesem noch nicht auf dem Server waren, hochgeladen und dann dort das Ziel aktualisiert." ], - "command": "git push origin foo^:master", + "command": "git push origin foo^:main", "beforeCommand": "git clone; go -b foo; git commit; git commit" } }, @@ -503,7 +651,7 @@ exports.level = { "afterMarkdowns": [ "Schick, das ist ziemlich praktisch. :D" ], - "command": "git push origin master:newBranch", + "command": "git push origin main:newBranch", "beforeCommand": "git clone; git commit" } }, @@ -511,7 +659,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Um dieses Level zu schaffen versuch den dargestellten Zielzustand zu erreichen und vergiss nicht das Format:", + "Um dieses Level zu schaffen versuche den dargestellten Zielzustand zu erreichen und vergiss nicht das Format:", "", "`:`" ] @@ -527,7 +675,7 @@ exports.level = { "markdowns": [ "## Подробности аргумента `<пункт назначения>`", "", - "Помните, когда в прошлом занятии мы указали в качестве аргумента ветку `master` для команды git push, мы указали совместно *источник*, откуда будут приходить коммиты, и *пункт назначения (получатель)*, куда коммиты будут уходить.", + "Помните, когда в прошлом занятии мы указали в качестве аргумента ветку `main` для команды git push, мы указали совместно *источник*, откуда будут приходить коммиты, и *пункт назначения (получатель)*, куда коммиты будут уходить.", "", "Однако, вы, наверное, задаётесь вопросом - а что, если я хочу, чтобы мои источник и получатель коммитов были различными? Что, если мы хотим запушить коммиты из локальной ветки `foo` в ветку `bar` на удалённом репозитории?", "", @@ -560,7 +708,7 @@ exports.level = { "afterMarkdowns": [ "Вау! Это довольно нетривиальная команда, однако она имеет смысл - git видит в `foo^` не что иное, как местоположение, закачивает все коммиты, которые не присутствуют на удалённом репозитории, и затем обновляет получателя." ], - "command": "git push origin foo^:master", + "command": "git push origin foo^:main", "beforeCommand": "git clone; go -b foo; git commit; git commit" } }, @@ -573,7 +721,7 @@ exports.level = { "afterMarkdowns": [ "Класс! Довольно легко! :D" ], - "command": "git push origin master:newBranch", + "command": "git push origin main:newBranch", "beforeCommand": "git clone; git commit" } }, @@ -598,7 +746,7 @@ exports.level = { "## `` 인자에 대한 세부사항들", "", "", - "기억하세요? 이전 강의에서 우리는 `master`를 커밋의 근원이되는 *source*와 목적지가 되는 *destination*으로 명령어의 인자로 넣어줌으로써 지정해줬습니다.", + "기억하세요? 이전 강의에서 우리는 `main`를 커밋의 근원이되는 *source*와 목적지가 되는 *destination*으로 명령어의 인자로 넣어줌으로써 지정해줬습니다.", "여러분은 이런 생각이 들 수 있어요 -- 내가 source와 destination이 다르길 원하면 어떻게 해야되지? 로컬의 `foo` 브랜치에서 원격의 `bar` 브랜치로 커밋을 push하고 싶으면 어떻게 해야 되지?", "", "사실 git에서는 그게 불가능합니다... 네 농담이고! 당연 가능합니다 :)... git의 어마무시하게 유연합니다(지나칠정도로요).", @@ -630,7 +778,7 @@ exports.level = { "afterMarkdowns": [ "워 뭔가 잘 안쓸것 같은 명령이지만 잘 됩니다 -- git은 `foo^`의 위치를 알아내서 원격 저장소에 아직 반영되지 않은 커밋들을 업로드하고 destination 브랜치를 갱신했습니다." ], - "command": "git push origin foo^:master", + "command": "git push origin foo^:main", "beforeCommand": "git clone; go -b foo; git commit; git commit" } }, @@ -643,7 +791,7 @@ exports.level = { "afterMarkdowns": [ "좋네요, 번지르르 삐까뻔쩍 :D" ], - "command": "git push origin master:newBranch", + "command": "git push origin main:newBranch", "beforeCommand": "git clone; git commit" } }, @@ -667,7 +815,7 @@ exports.level = { "markdowns": [ "## Детальніше про аргумент ``", "", - "З попереднього уроку нам відомо, що коли ми вказуємо `master` в якості аргумента place для git push, ми задаємо і гілку, *з якої* брати нові коміти, і гілку *до якої* їх буде перенесено.", + "З попереднього уроку нам відомо, що коли ми вказуємо `main` в якості аргумента place для git push, ми задаємо і гілку, *з якої* брати нові коміти, і гілку *до якої* їх буде перенесено.", "", "Тут ти можеш задуматись, а чи можуть гілки, звідки беремо, і куди переносимо, бути різними? Що, коли потрібно коміти з локальної гілки `foo` перенести у віддалену гілку `bar`?", "", @@ -700,7 +848,7 @@ exports.level = { "afterMarkdowns": [ "Овва! Це доволі незвична команда, але тут все має сенс -- git, знаючи куди вказує `foo^`, завантажив на віддалену сторону ще відсутні там коміти і оновив місце призначення." ], - "command": "git push origin foo^:master", + "command": "git push origin foo^:main", "beforeCommand": "git clone; go -b foo; git commit; git commit" } }, @@ -713,7 +861,7 @@ exports.level = { "afterMarkdowns": [ "Спритно, еге-ж? :D" ], - "command": "git push origin master:newBranch", + "command": "git push origin main:newBranch", "beforeCommand": "git clone; git commit" } }, @@ -728,6 +876,146 @@ exports.level = { } } ] + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Chi tiết về tham số ``", + "", + "Nhớ lại học trước, khi chỉ định tham số `` là `main` cho lệnh `git push`, ta cũng đã chỉ định nguồn và đích cho các commit.", + "", + "Có thể bạn sẽ thắng mắc -- Nếu như ta muốn nguồn và đích khác đi thì sao? Nếu như ta muốn đẩy commit từ nhánh cục bộ `foo` lên nhánh từ xa `bar` thì sao?", + "", + "Chà đáng tiếc là điều này là bất khả thi tron git... đùa thôi! Tất nhiên là làm được chứ :)... git có nhiều và rất nhiều lựa chọn linh động(có lẽ là quá nhiều)", + "", + "Hãy xem cách nó hoạt động ..." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Để chỉ định `` cho cả nguồn và đích, chỉ cần sử dụng dấu hai chấm `:` để kết nối cả hai:", + "", + "`git push origin :<đích>`", + "", + "Giá trị thực của tham số này là một refspec, \"refspec\" là một từ tự tạo, nghĩa là một vị trí được Git nhận ra (chẳng hạn như nhánh `foo` hoặc` HEAD ~ 1`).", + "", + "Một khi bạn đã chỉ định các nguồn và đích độc lập, bạn có thể thao tác với kho chứa từ xa một cách khá thú vị và chính xác, hãy xem bản demo!" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Nhớ rằng, `nguồn` là bất kỳ vị trí nào mà git hiểu:" + ], + "afterMarkdowns": [ + "Wao! Lệnh này khá phức tạp, nhưng mà hợp lý -- git diễn giải `foo^` thành một vị trí, tải lên tất cả các commit từ đó trở về trước mà chưa có trên nhánh đích rồi cập nhật nó." + ], + "command": "git push origin foo^:main", + "beforeCommand": "git clone; go -b foo; git commit; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Nếu như đích đến mà bạn muốn không tồn tại thì sao? Chẳng sao cả! Đơn giản hãy gõ tên nhánh và git sẽ tạo nhánh đó trên kho chứa từ xa cho bạn." + ], + "afterMarkdowns": [ + "Tuyệt vời, thấy git thú vị không :D" + ], + "command": "git push origin main:newBranch", + "beforeCommand": "git clone; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Ở cấp độ này, hãy hoàn thành mục tiêu được mô tả, và hãy nhớ cấu trúc:", + "", + "`:<đích>`" + ] + } + } + ] + }, + "sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Podrobnosti `` argumenta", + "", + "Spomni se prejšnje lekcije, kjer smo določili `main` kot place argument za git push, določili smo *izvor* iz kje bodo commiti prišli in *destinacijo*, kamor bodo commiti odšli.", + "", + "Morda se sprašuješ -- kaj če želimo, da sta izvor in destinacija različna? Kaj če želiš pushati commite iz lokalnega `foo` brancha na oddaljen `bar` branch?", + "", + "Nažalost to v gitu ni možno ... hecam se! Seveda je možno :) ... git ima ogromno opcij (skoraj preveč).", + "", + "Poglejmo kako v naslednjem razdelku ..." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Da bi določili in izvor in destinacijo ``, preprosto združimo oba skupaj z dvopičjem:", + "", + "`git push origin :`", + "", + "To je pogosto omenjeno kot dvopična referenca. Ta referenca je samo ime za lokacijo, ki jo lahko git razvozla (kot je branch `foo` ali samo `HEAD~1`).", + "", + "Ko enkrat določiš izvor in destinacijo neodvisno, lahko oddaljene ukaze uporabljaš zelo natačno in učinkovito. Poglejmo si primer!" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Pomni, `source` je bilokatera lokacija, ki jo git razume:" + ], + "afterMarkdowns": [ + "Woah! To je kar zanimiv ukaz, ampak ima smisel -- git je razrešil `foo^` v lokacijo, naložil commite, ki še niso bili prisotni v oddaljenem repotu in nato posodobil destinacijo." + ], + "command": "git push origin foo^:main", + "beforeCommand": "git clone; go -b foo; git commit; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Kaj če destinacija kamor želiš pushati ne obstaja? Ni problem! Samo podaj ime brancha in git bo naredil branch na oddaljenem repotu zate." + ], + "afterMarkdowns": [ + "Lepa, to je kar kul :D" + ], + "command": "git push origin main:newBranch", + "beforeCommand": "git clone; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Za to stopnjo poizkusi priti v ciljno stanje, prikazano v vizualizaciji in si zapomni obliko:", + "", + "`:`" + ] + } + } + ] } } }; diff --git a/src/levels/remote/pushManyFeatures.js b/src/levels/remote/pushManyFeatures.js index 976fd613..a63a7366 100644 --- a/src/levels/remote/pushManyFeatures.js +++ b/src/levels/remote/pushManyFeatures.js @@ -1,32 +1,40 @@ exports.level = { "goalTreeString": "%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C7%27%22%2C%22id%22%3A%22master%22%2C%22remoteTrackingBranchID%22%3A%22o/master%22%2C%22localBranchesThatTrackThis%22%3Anull%7D%2C%22o/master%22%3A%7B%22target%22%3A%22C7%27%22%2C%22id%22%3A%22o/master%22%2C%22remoteTrackingBranchID%22%3Anull%2C%22localBranchesThatTrackThis%22%3A%5B%22master%22%5D%7D%2C%22side1%22%3A%7B%22target%22%3A%22C2%27%22%2C%22id%22%3A%22side1%22%2C%22remoteTrackingBranchID%22%3Anull%2C%22localBranchesThatTrackThis%22%3Anull%7D%2C%22side2%22%3A%7B%22target%22%3A%22C4%27%22%2C%22id%22%3A%22side2%22%2C%22remoteTrackingBranchID%22%3Anull%2C%22localBranchesThatTrackThis%22%3Anull%7D%2C%22side3%22%3A%7B%22target%22%3A%22C7%27%22%2C%22id%22%3A%22side3%22%2C%22remoteTrackingBranchID%22%3Anull%2C%22localBranchesThatTrackThis%22%3Anull%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C4%22%3A%7B%22parents%22%3A%5B%22C3%22%5D%2C%22id%22%3A%22C4%22%7D%2C%22C5%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C5%22%7D%2C%22C6%22%3A%7B%22parents%22%3A%5B%22C5%22%5D%2C%22id%22%3A%22C6%22%7D%2C%22C7%22%3A%7B%22parents%22%3A%5B%22C6%22%5D%2C%22id%22%3A%22C7%22%7D%2C%22C8%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C8%22%7D%2C%22C2%27%22%3A%7B%22parents%22%3A%5B%22C8%22%5D%2C%22id%22%3A%22C2%27%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C2%27%22%5D%2C%22id%22%3A%22C3%27%22%7D%2C%22C4%27%22%3A%7B%22parents%22%3A%5B%22C3%27%22%5D%2C%22id%22%3A%22C4%27%22%7D%2C%22C5%27%22%3A%7B%22parents%22%3A%5B%22C4%27%22%5D%2C%22id%22%3A%22C5%27%22%7D%2C%22C6%27%22%3A%7B%22parents%22%3A%5B%22C5%27%22%5D%2C%22id%22%3A%22C6%27%22%7D%2C%22C7%27%22%3A%7B%22parents%22%3A%5B%22C6%27%22%5D%2C%22id%22%3A%22C7%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%2C%22originTree%22%3A%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C7%27%22%2C%22id%22%3A%22master%22%2C%22remoteTrackingBranchID%22%3Anull%2C%22localBranchesThatTrackThis%22%3Anull%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C8%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C8%22%7D%2C%22C2%27%22%3A%7B%22parents%22%3A%5B%22C8%22%5D%2C%22id%22%3A%22C2%27%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C2%27%22%5D%2C%22id%22%3A%22C3%27%22%7D%2C%22C4%27%22%3A%7B%22parents%22%3A%5B%22C3%27%22%5D%2C%22id%22%3A%22C4%27%22%7D%2C%22C5%27%22%3A%7B%22parents%22%3A%5B%22C4%27%22%5D%2C%22id%22%3A%22C5%27%22%7D%2C%22C6%27%22%3A%7B%22parents%22%3A%5B%22C5%27%22%5D%2C%22id%22%3A%22C6%27%22%7D%2C%22C7%27%22%3A%7B%22parents%22%3A%5B%22C6%27%22%5D%2C%22id%22%3A%22C7%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%7D%7D", - "solutionCommand": "git fetch;git rebase o/master side1;git rebase side1 side2;git rebase side2 side3;git rebase side3 master;git push", + "solutionCommand": "git fetch;git rebase o/main side1;git rebase side1 side2;git rebase side2 side3;git rebase side3 main;git push", "startTree": "{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\",\"localBranchesThatTrackThis\":null},\"o/master\":{\"target\":\"C1\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":[\"master\"]},\"side1\":{\"target\":\"C2\",\"id\":\"side1\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null},\"side2\":{\"target\":\"C4\",\"id\":\"side2\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null},\"side3\":{\"target\":\"C7\",\"id\":\"side3\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C3\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C1\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C5\"],\"id\":\"C6\"},\"C7\":{\"parents\":[\"C6\"],\"id\":\"C7\"}},\"HEAD\":{\"target\":\"side3\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C8\",\"id\":\"master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C8\":{\"parents\":[\"C1\"],\"id\":\"C8\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", "hint": { "en_US": "Remember you can always use the undo or reset commands", "zh_CN": "你随时都可以使用 undo 或 reset 命令。", "zh_TW": "你隨時都可以使用 undo 或 reset 指令。", "es_AR": "Acordate que siempre podés usar los comandos reset y undo", + "es_ES": "Recuerda que siempre puedes usar los comandos reset y undo", "pt_BR": "Lembre-se que você sempre pode usar undo ou reset", + "gl" : "Lembra que sempre podes usar undo ou reset", "de_DE": "Denk dran, du kannst immer undo oder reset benutzen, um deine Befehle zurück zu nehmen.", "ja" : "undoやresetコマンドをいつでも使用することができるのをお忘れなく", "fr_FR": "Rappelez-vous que vous pouvez toujours utiliser les commandes undo et reset.", "ru_RU": "Помни - ты всегда можешь отменить команды с помощью undo или reset", "ko" : "명령어를 undo와 reset으로 되돌릴 수 있다는 것을 잊지마세요", - "uk" : "Пам'ятай, ти в будь-який момент можеш використовувати команди undo або reset" + "uk" : "Пам'ятай, ти в будь-який момент можеш використовувати команди undo або reset", + "vi" : "Nhớ rằng bạn luôn luôn có thể hoàn tác hoặc soạn lại câu lệnh ", + "sl_SI": "Vedno lahko razveljaviš ukaz ali ponastaviš stopnjo." }, "name": { "en_US": "Push Master!", "zh_CN": "推送主分支", - "zh_TW": "push master!", + "zh_TW": "push main!", "es_AR": "¡Push Master!", + "es_ES": "¡Push Master!", "pt_BR": "Push Master!", + "gl" : "Empurra ó Master!", "de_DE": "Push Master!", "ja" : "Push Master!", "fr_FR": "Maître du push !", "ru_RU": "Push Мастер!", "ko" : "Push Master!", - "uk" : "Push Maйстер!" + "uk" : "Push Maйстер!", + "vi" : "Push Master!", + "sl_SI": "Push Master!" }, "compareOnlyMasterHashAgnostic": true, "startDialog": { @@ -38,15 +46,15 @@ exports.level = { "markdowns": [ "## Merging feature branches", "", - "Now that you're comfortable with fetching, pulling, and pushing, lets put these skills to the test with a new workflow.", + "Now that you're comfortable with fetching, pulling, and pushing, let's put these skills to the test with a new workflow.", "", - "It's common for developers on big projects to do all their work on feature branches (off of `master`) and then integrate that work only once it's ready. This is similar to the previous lesson (where side branches get pushed to the remote), but here we introduce one more step.", + "It's common for developers on big projects to do all their work on feature branches (off of `main`) and then integrate that work only once it's ready. This is similar to the previous lesson (where side branches get pushed to the remote), but here we introduce one more step.", "", - "Some developers only push and pull when on the `master` branch -- that way `master` always stays updated to what is on the remote (`o/master`).", + "Some developers only push and pull when on the `main` branch -- that way `main` always stays updated to what is on the remote (`o/main`).", "", "So for this workflow we combine two things:", "", - "* integrating feature branch work onto `master`, and", + "* integrating feature branch work onto `main`, and", "* pushing and pulling from the remote" ] } @@ -55,7 +63,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Let's see a refresher real quick of how to update `master` and push work." + "Let's see a refresher real quick of how to update `main` and push work." ], "afterMarkdowns": [ "We executed two commands here that:", @@ -93,13 +101,13 @@ exports.level = { "", "Maintenant que vous êtes habitué à fetch, pull et push, mettons ces compétences à profit avec une autre approche de travail.", "", - "Il est commun pour les développeurs de gros projets de faire tout leur travail dans des \"feature branches\" dédiées à une fonctionnalité (en dehors de `master`) et d'intégrer ce travail au reste seulement une fois qu'il est prêt. C'est similaire à la leçon précédente (où les branches secondaires étaient pushées sur le dépôt distant), mais ici nous introduisons une étape supplémentaire.", + "Il est commun pour les développeurs de gros projets de faire tout leur travail dans des \"feature branches\" dédiées à une fonctionnalité (en dehors de `main`) et d'intégrer ce travail au reste seulement une fois qu'il est prêt. C'est similaire à la leçon précédente (où les branches secondaires étaient pushées sur le dépôt distant), mais ici nous introduisons une étape supplémentaire.", "", - "Certains développeurs utilisent la méthode \"push puis pull\" uniquement sur la branche `master` : de cette manière `master` reste toujours à jour avec ce qu'il y a sur le dépôt distant (`o/master`).", + "Certains développeurs utilisent la méthode \"push puis pull\" uniquement sur la branche `main` : de cette manière `main` reste toujours à jour avec ce qu'il y a sur le dépôt distant (`o/main`).", "", "Cette approche combine donc deux choses :", "", - "* intégrer le travail présent depuis la feature branch (la fonctionnalité développée) vers `master`, puis", + "* intégrer le travail présent depuis la feature branch (la fonctionnalité développée) vers `main`, puis", "* pusher et puller sur le dépôt distant." ] } @@ -108,7 +116,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Rappelons-nous rapidement comment mettre à jour `master` et envoyer (push) le travail." + "Rappelons-nous rapidement comment mettre à jour `main` et envoyer (push) le travail." ], "afterMarkdowns": [ "Nous exécutons ici deux commandes :", @@ -124,7 +132,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Ce niveau est assez conséquent ; voici l'idée générale de la solution :", + "Ce niveau est assez conséquent; voici l'idée générale de la solution :", "", "* Il y a trois feature branches : `side1` `side2` et `side3`", "* Nous voulons envoyer chacune de ces modifications, dans l'ordre, sur le dépôt distant", @@ -146,13 +154,13 @@ exports.level = { "", "Ahora que estás cómodo fetcheando, pulleando y pusheando, pongamos a prueba estas habilidades con un nuevo flujo de trabajo.", "", - "Es bastante común que los desarrolladores en los grandes proyectos trabajen sobre ramas específicas para cada tarea (feature branches) basadas en `master`, y que las integren sólo cuando están listas. Esto es similar a la lección anterior, en que pusheabamos las ramas periféricas al remoto, pero acá tenemos un paso más.", + "Es bastante común que los desarrolladores en los grandes proyectos trabajen sobre ramas específicas para cada tarea (feature branches) basadas en `main`, y que las integren sólo cuando están listas. Esto es similar a la lección anterior, en que pusheabamos las ramas periféricas al remoto, pero acá tenemos un paso más.", "", - "Algunos desarrolladores sólo pushean y pullean cuando están en `master`: de ese modo, `master` siempre se mantiene actualizado con el remoto (`o/master`).", + "Algunos desarrolladores sólo pushean y pullean cuando están en `main`: de ese modo, `main` siempre se mantiene actualizado con el remoto (`o/main`).", "", "Entonces, en este flujo de trabajo combinamos dos cosas:", "", - "* integramos el trabajo de las ramas específicas a `master`, y", + "* integramos el trabajo de las ramas específicas a `main`, y", "* pusheamos y pulleamos del remoto" ] } @@ -161,7 +169,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Refresquemos un poco cómo actualizar `master` y pushear nuestro trabajo." + "Refresquemos un poco cómo actualizar `main` y pushear nuestro trabajo." ], "afterMarkdowns": [ "Acá ejecutamos dos comandos que:", @@ -189,6 +197,59 @@ exports.level = { } ] }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Haciendo merge con ramas de trabajo", + "", + "Ahora que estás cómodo fetcheando, pulleando y pusheando, pongamos a prueba estas habilidades con un nuevo flujo de trabajo.", + "", + "Es bastante común que los desarrolladores en los grandes proyectos trabajen sobre ramas específicas para cada tarea (feature branches o ramas de trabajo) basadas en `main`, y que las integren sólo cuando estén listas. Esto es similar a la lección anterior, en la que hicimos push de las ramas periféricas al remoto, pero aquí tenemos un paso más.", + "", + "Algunos desarrolladores sólo pushean y pullean cuando están en `main`: de ese modo, `main` siempre se mantiene actualizado con el remoto (`o/main`).", + "", + "Entonces, en este flujo de trabajo combinamos dos cosas:", + "", + "* integramos el trabajo de las ramas específicas a `main`, y", + "* pusheamos y pulleamos del remoto" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Refresquemos un poco cómo actualizar `main` y pushear nuestro trabajo." + ], + "afterMarkdowns": [ + "Ahora ejecutamos dos comandos que:", + "", + "* rebasearon nuestro trabajo sobre los nuevos commits del remoto, y", + "* publicamos nuestro trabajo en ese remoto" + ], + "command": "git pull --rebase; git push", + "beforeCommand": "git clone; git commit; git fakeTeamwork" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Este nivel es bastante pesado. Aquí tienes algunas ideas para resolverlo:", + "", + "* Tenemos tres ramas específicas -- `side1` `side2` and `side3`", + "* Queremos hacer push de cada una de esas ramas, en orden, al remoto", + "* El remoto fue actualizado, así que vamos a tener que integrar esos cambios también", + "", + ":O ¡Genial! ¡Éxito! Completar este nivel representa un gran avance." + ] + } + } + ] + }, "pt_BR": { "childViews": [ { @@ -199,13 +260,13 @@ exports.level = { "", "Agora que você está confortável com fetch, pull e push, vamos colocar essas habilidades em teste com um novo fluxo de trabalho.", "", - "É comum para desenvolvedores de grande projetos fazer todo o trabalho em ramos de funcionalidades (fora do `master`) e então integrar esse trabalho uma única vez quando ele estiver pronto. Isso é similar à lição anterior (onde ramos laterais eram enviados ao repositório remoto), mas introduzimos mais um passo.", + "É comum para desenvolvedores de grande projetos fazer todo o trabalho em ramos de funcionalidades (fora do `main`) e então integrar esse trabalho uma única vez quando ele estiver pronto. Isso é similar à lição anterior (onde ramos laterais eram enviados ao repositório remoto), mas introduzimos mais um passo.", "", - "Alguns desenvolvedores só fazem push e pull quando no ramo `master` -- desta forma o `master` sempre se mantém atualizado com aquilo que está no ramo remoto (`o/master`).", + "Alguns desenvolvedores só fazem push e pull quando no ramo `main` -- desta forma o `main` sempre se mantém atualizado com aquilo que está no ramo remoto (`o/main`).", "", "Então, para este fluxo de trabalho, combinaremos duas coisas:", "", - "* Integrar ramos de funcionalidade no `master`, e", + "* Integrar ramos de funcionalidade no `main`, e", "* Realizar push e pull do repositório remoto" ] } @@ -214,7 +275,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Vamos refrescar a memória sobre como atualizar o `master` e enviar trabalho." + "Vamos refrescar a memória sobre como atualizar o `main` e enviar trabalho." ], "afterMarkdowns": [ "Nós executamos dois comandos aqui que:", @@ -242,6 +303,59 @@ exports.level = { } ] }, + "gl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Mesturando ramas", + "", + "Agora que estás afeito a descargar, mesturar e empurrar, poñamos a proba estas habilidades cun novo fluxo de traballo.", + "", + "É bastante común que os desenvolvedores nos grandes proxectos traballen sobre ramas específicas para cada tarefa (feature branches) baseadas en `mater`, e que as integren só cando están preparadas. Esto é similar á lección anterior, na que empurrábamos as ramas periféricas ó remoto, pero acá temos un paso máis.", + "", + "Algúns desenvovledores só empurran e descargan cando están en `main`: de ese xeito, `main` sempre mantén actualizado o seu estado co remoto (`o/main`).", + "", + "Entón, neste fluxo de traballo combinamos dúas cousas:", + "", + "* integramos o traballo das ramas específicas a `main`, e", + "* empurramos e turramos do remoto" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Refresquemos un pouco cómo actualizar `main` e empurrar o noso traballo." + ], + "afterMarkdowns": [ + "Agora executamos dous comandos que:", + "", + "* rebasamos o noso traballo sobre os novos commits do remoto, e", + "* publicamos o noso traballo nese remoto" + ], + "command": "git pull --rebase; git push", + "beforeCommand": "git clone; git commit; git fakeTeamwork" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Este nivel é bastante pesado. Aquí tes algúns patróns para resolvelo:", + "", + "* Temos tres ramas específicas -- `side1` `side2` e `side3`", + "* Queremos empurrar cada unha de esas ramas, en orde, ó remoto", + "* O remoto foi actualizado, así que imos ter que integrar eses cambios tamén", + "", + ":O ¡Intenso! ¡Éxitos! Completar este nivel representa un grande avance." + ] + } + } + ] + }, "zh_TW": { "childViews": [ { @@ -252,13 +366,13 @@ exports.level = { "", "現在你已經很熟悉 fetch、pull 以及 push,讓我們來針對一個新的問題來應用這些技巧。", "", - "在一個大型的專案裡面,程式設計師經常會在 feature branch(有別於 master branch)上面做開發,之後等開發完之後,在一次 merge 回去。這跟之前的課程是很類似的(其它的 branch 被 push 到 remote),但是現在我們還要再多介紹一個步驟。", + "在一個大型的專案裡面,程式設計師經常會在 feature branch(有別於 main branch)上面做開發,之後等開發完之後,在一次 merge 回去。這跟之前的課程是很類似的(其它的 branch 被 push 到 remote),但是現在我們還要再多介紹一個步驟。", "", - "某些程式設計師只針對 `master` branch 進行 push 或者是 pull。這樣子的話 `master` 一直都保持跟 remote (`o/master`) 同步。", + "某些程式設計師只針對 `main` branch 進行 push 或者是 pull。這樣子的話 `main` 一直都保持跟 remote (`o/main`) 同步。", "", "所以針對這個問題我們結合了兩件事情:", "", - "* merge feature branch 到`master` branch,並且", + "* merge feature branch 到`main` branch,並且", "* push remote 以及 pull remote" ] } @@ -267,7 +381,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "讓我們馬上來實際看一下如何更新 `master` 並且 push 到 remote。" + "讓我們馬上來實際看一下如何更新 `main` 並且 push 到 remote。" ], "afterMarkdowns": [ "我們在這裡執行兩個指令:", @@ -303,15 +417,15 @@ exports.level = { "markdowns": [ "## Einen Feature Branch reintegrieren", "", - "Nun da du mit `fetch`, `pull`, und `push` vertraut bist sollten wir diese Fähigkeiten mit einem neuen Arbeitsablauf auf die Probe stellen.", + "Nun da du mit `fetch`, `pull`, und `push` vertraut bist, sollten wir diese Fähigkeiten mit einem neuen Arbeitsablauf auf die Probe stellen.", "", - "Für Entwickler in großen Projekten ist es nicht ungewöhnlich ihre Arbeit in Feature Branches (von `master` abgeleitet) zu erledigen und dann diese Inhalte zu reintegrieren, wenn sie fertig sind. Das ist ähnlich dem vorherigen Level (in dem ein Feature Branch auf den Server geschoben wird), nur mit einem zusätzlichen Schritt.", + "Für Entwickler in großen Projekten ist es nicht ungewöhnlich ihre Arbeit in Feature Branches (von `main` abgeleitet) zu erledigen und dann diese Inhalte zu reintegrieren, wenn sie fertig sind. Das ist ähnlich dem vorherigen Level (in dem ein Feature Branch auf den Server geschoben wird), nur mit einem zusätzlichen Schritt.", "", - "Einige Entwickler pushen und pullen nur auf dem `master` -- dadurch ist `master` immer aktuell zu seinem Gegenstück auf dem Server (`o/master`).", + "Einige Entwickler pushen und pullen nur auf dem `main` -- dadurch ist `main` immer aktuell zu seinem Gegenstück auf dem Server (`o/main`).", "", "Für diesen Ablauf werden wir also zwei Dinge kombinieren:", "", - "* einen Feature Branch in `master` reintegrieren und", + "* einen Feature Branch in `main` reintegrieren und", "* vom entfernten Server pushen und pullen." ] } @@ -320,7 +434,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Schauen wir uns zur Erinnerung schnell noch mal an wie man den `master` aktualisiert und seine Commits pusht." + "Schauen wir uns zur Erinnerung schnell noch mal an, wie man den `main` aktualisiert und seine Commits pusht." ], "afterMarkdowns": [ "Wir haben hier zwei Befehle ausgeführt, die:", @@ -358,13 +472,13 @@ exports.level = { "", "既然你应该很熟悉 fetch、pull、push 了,现在我们要通过一个新的工作流来测试你的这些技能。", "", - "在大型项目中开发人员通常会在(从 `master` 上分出来的)特性分支上工作,工作完成后只做一次集成。这跟前面课程的描述很相像(把 side 分支推送到远程仓库),不过本节我们会深入一些.", + "在大型项目中开发人员通常会在(从 `main` 上分出来的)特性分支上工作,工作完成后只做一次集成。这跟前面课程的描述很相像(把 side 分支推送到远程仓库),不过本节我们会深入一些.", "", - "但是有些开发人员只在 master 上做 push、pull —— 这样的话 master 总是最新的,始终与远程分支 (o/master) 保持一致。", + "但是有些开发人员只在 main 上做 push、pull —— 这样的话 main 总是最新的,始终与远程分支 (o/main) 保持一致。", "", "对于接下来这个工作流,我们集成了两个步骤:", "", - "* 将特性分支集成到 `master` 上", + "* 将特性分支集成到 `main` 上", "* 推送并更新远程分支" ] } @@ -373,7 +487,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "让我们看看如何快速的更新 `master` 分支并推送到远程。" + "让我们看看如何快速的更新 `main` 分支并推送到远程。" ], "afterMarkdowns": [ "我们执行了两个命令: ", @@ -411,13 +525,13 @@ exports.level = { "", "Теперь, когда вы умело владеете командами fetch, pull и push, давайте применим эти навыки в сочетании с новым рабочим процессом (он же workflow).", "", - "Среди разработчиков, вовлечённых в большой проект, довольно распространённ приём — выполнять всю свою работу в так называемых фича-бранчах (вне `master`). А затем, как только работа выполнена, разработчик интегрирует всё, что было им сделано. Всё это, за исключением одного шага, похоже на предыдущий урок (там, где мы закачивали ветки на удалённый репозиторий)", + "Среди разработчиков, вовлечённых в большой проект, довольно распространённ приём — выполнять всю свою работу в так называемых фича-бранчах (вне `main`). А затем, как только работа выполнена, разработчик интегрирует всё, что было им сделано. Всё это, за исключением одного шага, похоже на предыдущий урок (там, где мы закачивали ветки на удалённый репозиторий)", "", - "Ряд разработчиков делают push и pull лишь на локальную ветку `master` - таким образом ветка `master` всегда синхронизирована с тем, что находится на удалённом репозитории (`o/master`).", + "Ряд разработчиков делают push и pull лишь на локальную ветку `main` - таким образом ветка `main` всегда синхронизирована с тем, что находится на удалённом репозитории (`o/main`).", "", "Для этого рабочего процесса мы совместили две вещи:", "", - "* интеграцию фича-бранчей в `master`", + "* интеграцию фича-бранчей в `main`", "* закачку (push) и скачку (pull) с удалённого репозитория" ] } @@ -426,7 +540,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Давайте быстренько вспомним, как нам обновить `master` и закачать выполненную работу." + "Давайте быстренько вспомним, как нам обновить `main` и закачать выполненную работу." ], "afterMarkdowns": [ "Здесь мы выполнили две команды, которые:", @@ -464,13 +578,13 @@ exports.level = { "", "今や、あなたは`fetch`、`pull`、`push`を十分に使えるようになったでしょうから、そのスキルを新しい作業の流れで試してみましょう。", "", - "大きなプロジェクトの開発者にとって、フィーチャーブランチ(`master`を除く)上で全ての作業を行い、完成したら一度でその作業を統合するというような流れが一般的です。これは前のレッスンの内容(他のブランチからリモートにプッシュされるような状況のところが)に似ていますが、ここではもう一歩踏み込んで解説しましょう。", + "大きなプロジェクトの開発者にとって、フィーチャーブランチ(`main`を除く)上で全ての作業を行い、完成したら一度でその作業を統合するというような流れが一般的です。これは前のレッスンの内容(他のブランチからリモートにプッシュされるような状況のところが)に似ていますが、ここではもう一歩踏み込んで解説しましょう。", "", - "開発者は、`master`ブランチにいるときプッシュとプルしかしません -- `master`は常にリモート(`o/master`)に追従した状態のままにします。", + "開発者は、`main`ブランチにいるときプッシュとプルしかしません -- `main`は常にリモート(`o/main`)に追従した状態のままにします。", "", "この作業の流れでは、私たちは二つのことを組み合わせています:", "", - "* `master`にフィーチャーブランチの作業を統合し、", + "* `main`にフィーチャーブランチの作業を統合し、", "* リモートへの`push`と`pull`を行う" ] } @@ -479,7 +593,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "`master`の更新と作業の反映の方法を手早く復習しましょう。" + "`main`の更新と作業の反映の方法を手早く復習しましょう。" ], "afterMarkdowns": [ "我々はここで二つのコマンドを動かしました:", @@ -517,13 +631,13 @@ exports.level = { "", "이제 여러분은 fetch, pull, push하는데에 익숙해졌을겁니다. 연마한 기술들을 새로운 상황에서 시험 해봅시다.", "", - "개발자들은 주로 큰 프로젝트를 개발할때 작업을 feature 브랜치(=토픽브랜치 / `master`브랜치가 아닌 작업을위해 임시로 만든 브랜치를 말합니다)들에 하고 준비가 되면 그 작업을 통합합니다. 이전 강의와 비슷한 모습인데(사이드 브랜치들을 원격저장소로 push한것), 여기서 한 단계 더 나아가 봅시다. ", + "개발자들은 주로 큰 프로젝트를 개발할때 작업을 feature 브랜치(=토픽브랜치 / `main`브랜치가 아닌 작업을위해 임시로 만든 브랜치를 말합니다)들에 하고 준비가 되면 그 작업을 통합합니다. 이전 강의와 비슷한 모습인데(사이드 브랜치들을 원격저장소로 push한것), 여기서 한 단계 더 나아가 봅시다. ", "", - "어떤 개발자들은 `master` 브랜치에 있을때만 push와 pull을 수행합니다 -- 이렇게하면 `master`는 항상 원격 브랜치 (`o/master`)의 상태와 항상 최신의 상태로 유지될 수 있습니다.", + "어떤 개발자들은 `main` 브랜치에 있을때만 push와 pull을 수행합니다 -- 이렇게하면 `main`는 항상 원격 브랜치 (`o/main`)의 상태와 항상 최신의 상태로 유지될 수 있습니다.", "", "이런 작업흐름은 두가지 작업을 같이하게됩니다 :", "", - "* feature 브랜치의 작업을 master로 통합하는것과", + "* feature 브랜치의 작업을 main 브랜치로 통합하는것과", "* 원격저장소에서 push하고 pull하는 작업입니다" ] } @@ -532,7 +646,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "다음을 보고 `master`를 갱신하고 작업을 push하는 방법을 다시 떠올려봅시다." + "다음을 보고 `main`를 갱신하고 작업을 push하는 방법을 다시 떠올려봅시다." ], "afterMarkdowns": [ "여기서 우리는 두개의 명령어를 실행 했습니다 :", @@ -570,13 +684,13 @@ exports.level = { "", "Тепер, коли ти вже впевнено володієш засобами `pull` та `push`, час перевірити ці знання в новому процесі.", "", - "Зазвичай розробники працюють над якимось фічами в окремій гілці (не в `master`), а потім, коли роботу закінчено, інтегрують її. Це схоже на попередній урок (де окремі гілки пушили у віддалений репозиторій), але тут буде ще один додатковий крок.", + "Зазвичай розробники працюють над якимось фічами в окремій гілці (не в `main`), а потім, коли роботу закінчено, інтегрують її. Це схоже на попередній урок (де окремі гілки пушили у віддалений репозиторій), але тут буде ще один додатковий крок.", "", - "Деякі розробники виконують push і pull лише в гілці `master` -- тож `master` завжди буде актуальним і синхронізованим з віддаленою гілкою (`o/master`).", + "Деякі розробники виконують push і pull лише в гілці `main` -- тож `main` завжди буде актуальним і синхронізованим з віддаленою гілкою (`o/main`).", "", "Отже для цього процесу ми об'єднуємо дві речі:", "", - "* інтеграцію гілки з фічею в `master`, і", + "* інтеграцію гілки з фічею в `main`, і", "* пул та пуш для синхронізації з віддаленим репозиторієм" ] } @@ -585,7 +699,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Пригадаймо коротко як оновити `master` і запушити свої зміни." + "Пригадаймо коротко як оновити `main` і запушити свої зміни." ], "afterMarkdowns": [ "Ми виконали дві команди, які:", @@ -612,6 +726,112 @@ exports.level = { } } ] + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Sáp nhập các nhánh tính năng", + "", + "Giờ thì bạn đã quen thuộc với tìm nạp, kéo và đẩy, bây giờ chúng tôi sẽ kiểm tra kỹ năng của bạn với một quy trình làm việc mới.", + "", + "Trong các dự án lớn, các nhà phát triển thường làm việc trên các nhánh tính năng (được phân nhánh từ `main`) và chỉ thực hiện tích hợp sau khi công việc hoàn thành. Điều này tương tự như mô tả trong bài học trước (đẩy nhánh bên sang kho lưu trữ từ xa), nhưng chúng ta sẽ đi sâu hơn một chút trong phần này.", + "", + "Một vài nhà phát triển chỉ thực hiện đẩy và kéo khi ở trên nhánh `main` -- như vậy thì nhánh `main` luôn luôn được cập nhật với nhánh từ xa (`o/main`).", + "", + "Vậy nên với quy trình làm việc này chúng tôi đã kết hợp 2 việc:", + "", + "* tích hợp nhánh chức năng lên nhánh `main`, và", + "* đẩy và kéo từ nhánh từ xa" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Hãy xem qua cách cập nhật nhánh `main` và đẩy lên nhánh từ xa hoạt động như thế nào." + ], + "afterMarkdowns": [ + "Ta thực thi 2 câu lệnh làm việc sau:", + "", + "* tái bố trí (`rebase`) thành quả của ta lên commit của nhánh từ xa, và", + "* xuất bản thành quả của ta lên nhánh từ xa" + ], + "command": "git pull --rebase; git push", + "beforeCommand": "git clone; git commit; git fakeTeamwork" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Cấp độ này khá là phức tạp đấy -- để hoàn thành thì hãy xem qua hướng dẫn cơ bản sau:", + "", + "* Có 3 nhánh chức năng là -- `side1` `side2` vả `side3`", + "* Chúng tôi muốn bạn đẩy từng nhánh chức năng, theo thứ tự, lên nhánh từ xa", + "* Nhánh từ xa cũng đã được cập nhật, nên ta cũng cần sát nhập thay đổi đó nữa", + "", + ":O khoai đây! Cố lên nhé, hoàn thành cấp độ này là lên trình nhiều lắm đấy." + ] + } + } + ] + }, + "sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Merganje funkcionalnih branchev", + "", + "Sedaj, ko se počutiš udobno s fetchanjem, pullanjem in pushanjem, preizkusimo ta znanja z novimi primeri.", + "", + "Za razvijalce na velikih projektih je pogosto, da delajo vse svoje stvari na funkcionalnih brancih (ne na `main`) in potem vključijo to delo, ko je končano. To je podobno prejšnjim lekcijam (kjer so bili pushani stranski branchi na oddaljen repo), a tu predstavljamo še en korak.", + "", + "Nekateri razvijaci samo pushajo in pullajo na `main` branchu -- zato `main` vedno ostane posodobljen z oddaljenim masterjem (`o/main`).", + "", + "Torej za tak primer uporabe, združimo dve stvari:", + "", + "* vključevanje dela funkcionalnih branchev na `main` in", + "* pushanje in pullanje iz oddaljenega repota" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Osvežimo si na hitro, kako posodobiti `main` in pushati delo." + ], + "afterMarkdowns": [ + "Izvedli smo dva ukaza, ki:", + "", + "* rebasata naše delo na nove commite iz oddaljenega repozitorija in", + "* objavita naše delo na oddaljen repozitorij" + ], + "command": "git pull --rebase; git push", + "beforeCommand": "git clone; git commit; git fakeTeamwork" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Ta stopnja je kar zajetna -- tu je splošno ideja za rešitev:", + "", + "* Imamo tri branche -- `side1`, `side2` in `side3`", + "* Želimo pushati vsako od teh funkcionalnosti po vrstnem redu na oddaljen repo", + "* Oddaljen repo se je medtem posodobil, zato bomo morali vključiti tudi to delo", + "", + ":O Naporno! Srečno, končanje te stopnje je velik korak." + ] + } + } + ] } } }; diff --git a/src/levels/remote/remoteBranches.js b/src/levels/remote/remoteBranches.js index 92b6a6c6..097d0fd2 100644 --- a/src/levels/remote/remoteBranches.js +++ b/src/levels/remote/remoteBranches.js @@ -1,32 +1,40 @@ exports.level = { "goalTreeString": "{\"branches\":{\"master\":{\"target\":\"C3\",\"id\":\"master\"},\"o/master\":{\"target\":\"C1\",\"id\":\"o/master\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C1\"],\"id\":\"C4\"}},\"HEAD\":{\"target\":\"C4\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", - "solutionCommand": "git commit;git checkout o/master;git commit", + "solutionCommand": "git commit;git checkout o/main;git commit", "startTree": "{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\"},\"o/master\":{\"target\":\"C1\",\"id\":\"o/master\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", "name": { "en_US": "Remote Branches", "zh_CN": "远程分支", "zh_TW": "remote branch (遠端分支)", "es_AR": "Ramas remotas", + "es_ES": "Ramas remotas", "pt_BR": "Ramos remotos", + "gl" : "Ramas remotas", "de_DE": "Branches auf entfernten Servern", "ja" : "リモートのブランチ", "fr_FR": "Les branches distantes", "ru_RU": "Удалённые ветки", "ko" : "원격 브랜치(remote branch)", - "uk" : "Віддалені гілки" + "uk" : "Віддалені гілки", + "vi" : "Nhánh từ xa", + "sl_SI": "Oddaljeni Branchi" }, "hint": { - "en_US": "Pay attention to the ordering -- commit on master first!", - "zh_CN": "注意顺序 —— 先在 master 分支上提交!", - "zh_TW": "注意順序的問題喔!先在 master branch 上面送 commit", - "es_AR": "Prestá atención al orden: ¡commiteá sobre master primero!", - "pt_BR": "Preste atenção na ordem: commite no master primeiro!", - "de_DE": "Beachte die Sortierung -- committe zuerst auf dem master!", + "en_US": "Pay attention to the ordering -- commit on main first!", + "zh_CN": "注意顺序 —— 先在 main 分支上提交!", + "zh_TW": "注意順序的問題喔!先在 main branch 上面送 commit", + "es_AR": "Prestá atención al orden: ¡commiteá sobre main primero!", + "es_ES": "Presta atención al orden: ¡haz commit sobre main primero!", + "pt_BR": "Preste atenção na ordem: commite no main primeiro!", + "gl" : "Preta atención á orde: fai commit no main primeiro", + "de_DE": "Beachte die Sortierung -- committe zuerst auf dem main!", "ja" : "順番に注意 -- まずmasterに対してcommitしましょう", - "fr_FR": "Prêtez attention à l'ordre -- les commits sur master d'abord !", - "ru_RU": "Уделяйте внимание очерёдности -- сперва commit на master", - "ko" : "순서에 주의하세요 -- master에서 먼저 커밋하세요!", - "uk" : "Звертайте увагу на послідовність -- спочатку коміт в мастер!" + "fr_FR": "Prêtez attention à l'ordre -- les commits sur main d'abord !", + "ru_RU": "Уделяйте внимание очерёдности -- сперва commit на main", + "ko" : "순서에 주의하세요: main 브랜치 에서 먼저 커밋하세요!", + "uk" : "Звертайте увагу на послідовність -- спочатку коміт в мастер!", + "vi" : "Chú ý đến thứ tự -- commit trên nhánh main trước!", + "sl_SI": "Bodi pozoren na vrsti red -- commitaj najprej na main!" }, "startDialog": { "en_US": { @@ -39,7 +47,7 @@ exports.level = { "", "Now that you've seen `git clone` in action, let's dive into what actually changed.", "", - "The first thing you may have noticed is that a new branch appeared in our local repository called `o/master`. This type of branch is called a _remote_ branch; remote branches have special properties because they serve a unique purpose.", + "The first thing you may have noticed is that a new branch appeared in our local repository called `o/main`. This type of branch is called a _remote_ branch; remote branches have special properties because they serve a unique purpose.", "", "Remote branches reflect the _state_ of remote repositories (since you last talked to those remote repositories). They help you understand the difference between your local work and what work is public -- a critical step to take before sharing your work with others.", "", @@ -57,7 +65,7 @@ exports.level = { "", "* `/`", "", - "Hence, if you look at a branch named `o/master`, the branch name is `master` and the name of the remote is `o`.", + "Hence, if you look at a branch named `o/main`, the branch name is `main` and the name of the remote is `o`.", "", "Most developers actually name their main remote `origin`, not `o`. This is so common that git actually sets up your remote to be named `origin` when you `git clone` a repository.", "", @@ -71,12 +79,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Lets check out a remote branch and see what happens" + "Lets check out a remote branch and see what happens." ], "afterMarkdowns": [ - "As you can see, git put us into detached `HEAD` mode and then did not update `o/master` when we added a new commit. This is because `o/master` will only update when the remote updates." + "As you can see, git put us into detached `HEAD` mode and then did not update `o/main` when we added a new commit. This is because `o/main` will only update when the remote updates." ], - "command": "git checkout o/master; git commit", + "command": "git checkout o/main; git commit", "beforeCommand": "git clone" } }, @@ -84,7 +92,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "To finish this level, commit once off of `master` and once after checking out `o/master`. This will help drive home how remote branches behave differently, and they only update to reflect the state of the remote." + "To finish this level, commit once off of `main` and once after checking out `o/main`. This will help drive home how remote branches behave differently, and they only update to reflect the state of the remote." ] } } @@ -100,7 +108,7 @@ exports.level = { "", "Maintenant que nous avons vu `git clone` en action, plongeons dans ce qui a changé.", "", - "La première chose que vous avez peut-être remarqué est qu'une nouvelle branche est apparue dans votre dépôt local appelée `o/master`. Ce type de branche est appelée une branche _distante_ ; les branches distantes ont des propriétés spécifiques car elles servent à un but précis.", + "La première chose que vous avez peut-être remarqué est qu'une nouvelle branche est apparue dans votre dépôt local appelée `o/main`. Ce type de branche est appelée une branche _distante_ ; les branches distantes ont des propriétés spécifiques car elles servent à un but précis.", "", "Les branches distantes reflètent _l'état_ des dépôts distants (depuis la dernière fois où vous avez parlé avec ceux-ci). Elles vous aident à comprendre les différences entre votre travail et le travail public -- une étape critique à effectuer avant de partager son travail avec les autres.", "", @@ -118,7 +126,7 @@ exports.level = { "", "* `/`", "", - "Donc, si vous regardez une branche nommée `o/master`, le nom de la branche est `master` et le nom du dépôt distant est `o`.", + "Donc, si vous regardez une branche nommée `o/main`, le nom de la branche est `main` et le nom du dépôt distant est `o`.", "", "La plupart des développeurs nomment leur principal dépôt distant `origin`, pas `o`. C'est si commun que git configure en fait votre dépôt local pour être nommé `origin` quand vous faîtes un `git clone` du dépôt.", "", @@ -132,12 +140,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Rendons-nous sur une branche et regardons ce qui se passe" + "Rendons-nous sur une branche et regardons ce qui se passe." ], "afterMarkdowns": [ - "Comme vous pouvez le voir, git nous a mis dans le mode \"detached\" (cf. `HEAD`) puis n'a pas mis à jour `o/master` quand nous avons ajouté un nouveau commit. C'est parce que `o/master` va se mettre à jour uniquement quand le dépôt distant sera mis à jour." + "Comme vous pouvez le voir, git nous a mis dans le mode \"detached\" (cf. `HEAD`) puis n'a pas mis à jour `o/main` quand nous avons ajouté un nouveau commit. C'est parce que `o/main` va se mettre à jour uniquement quand le dépôt distant sera mis à jour." ], - "command": "git checkout o/master; git commit", + "command": "git checkout o/main; git commit", "beforeCommand": "git clone" } }, @@ -145,7 +153,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Pour finir ce niveau, faîtes un commit en dehors de `master` puis un après vous être rendu dans `o/master`. Cela va nous aider à comprendre la différence de comportement des branches distantes, et le fait qu'elles se mettent à jour uniquement pour refléter l'état du dépôt distant." + "Pour finir ce niveau, faîtes un commit en dehors de `main` puis un après vous être rendu dans `o/main`. Cela va nous aider à comprendre la différence de comportement des branches distantes, et le fait qu'elles se mettent à jour uniquement pour refléter l'état du dépôt distant." ] } } @@ -161,9 +169,9 @@ exports.level = { "", "Ahora que viste `git clone` en acción, ahondemos en lo que realmente cambió.", "", - "Lo primero que habrás notado es que apareció una nueva rama en tu repositorio local llamada `o/master`. A este tipo de ramas se las llama ramas _remotas_. Las ramas remotas tienen propiedades especiales porque sirven un propósito específico.", + "Lo primero que habrás notado es que apareció una nueva rama en tu repositorio local llamada `o/main`. A este tipo de ramas se las llama ramas _remotas_. Las ramas remotas tienen propiedades especiales porque sirven un propósito específico.", "", - "Las ramas remotas reflejan el _estado_ de los repositorios remotos (como estaban la última vez que hablaste con ellos). Te ayudan a entender las diferencias entre tu trabajo local y el trabajo que ya está publicado - un paso crítico antes de compartir tu trabajo con los demás.", + "Las ramas remotas reflejan el _estado_ de los repositorios remotos (cómo estaban la última vez que hablaste con ellos). Te ayudan a entender las diferencias entre tu trabajo local y el trabajo que ya está publicado - un paso crítico antes de compartir tu trabajo con los demás.", "", "Las ramas remotas tienen la propiedad especial de que cuando las checkouteás, pasás al modo detached `HEAD`. Git lo hace a propósito porque no podés trabajar en esas ramas directamente: tenés que trabajar en algún otro lado y después compartir tu trabajo con el remoto (tras lo que tus ramas remotas se actualizarán)." ] @@ -179,7 +187,7 @@ exports.level = { "", "* `/`", "", - "Entonces, si mirás una rama llamada `o/master`, el nombre de la rama es `master`, y el nombre del remoto es `o`.", + "Entonces, si mirás una rama llamada `o/main`, el nombre de la rama es `main`, y el nombre del remoto es `o`.", "", "La mayoría de los desarrolladores llaman `origin` a su remoto en lugar de `o`. Esto es tan común que git efectivamente crea tu remoto llamándolo `origin` cuando hacés `git clone` de un repositorio.", "", @@ -193,12 +201,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Checkouteemos una rama remota a ver qué pasa" + "Checkouteemos una rama remota a ver qué pasa." ], "afterMarkdowns": [ - "Como ves, git nos puso en el modo detached `HEAD` y no actualizó `o/master` cuando creamos un nuevo commit. Esto es porque `o/master` sólo va a actualizarse cuando el remoto se actualice." + "Como ves, git nos puso en el modo detached `HEAD` y no actualizó `o/main` cuando creamos un nuevo commit. Esto es porque `o/main` sólo va a actualizarse cuando el remoto se actualice." ], - "command": "git checkout o/master; git commit", + "command": "git checkout o/main; git commit", "beforeCommand": "git clone" } }, @@ -206,7 +214,68 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Para completar este nivel, commiteá una vez sobre `master` y una después de checkoutear `o/master`. Esto te va a ayudar a caer en cómo las ramas remotas funcionan distinto, y que sólo se actualizan para reflejar el estado del remoto." + "Para completar este nivel, commiteá una vez sobre `main` y una después de checkoutear `o/main`. Esto te va a ayudar a caer en cómo las ramas remotas funcionan distinto, y que sólo se actualizan para reflejar el estado del remoto." + ] + } + } + ] + }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Ramas remotas de git", + "", + "Ahora que viste `git clone` en acción, ahondemos en lo que realmente cambió.", + "", + "Lo primero que habrás notado es que apareció una nueva rama en tu repositorio local llamada `o/main`. A este tipo de ramas se las llama ramas _remotas_. Las ramas remotas tienen propiedades especiales porque sirven un propósito específico.", + "", + "Las ramas remotas reflejan el _estado_ de los repositorios remotos (cómo estaban la última vez que hablaste con ellos). Te ayudan a entender las diferencias entre tu trabajo local y el trabajo que ya está publicado - un paso crítico antes de compartir tu trabajo con los demás.", + "", + "Las ramas remotas tienen la propiedad especial de que cuando haces checkout sobre ellas, pasas al modo detached `HEAD`. Git lo hace a propósito porque no puedes trabajar en esas ramas directamente: tienes que trabajar en algún otro lado y después compartir tu trabajo con el remoto (tras lo que tus ramas remotas se actualizarán)." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### ¿Qué es `o/`?", + "", + "Podrías estar preguntándote qué significa ese `o/` al principio de las ramas remotas. Bueno, las ramas remotas también tienen una convención de nombres obligatoria -- se muestran con el formato:", + "", + "* `/`", + "", + "Entonces, si observas una rama llamada `o/main`, el nombre de la rama es `main`, y el nombre del remoto es `o`.", + "", + "La mayoría de los desarrolladores llaman `origin` a su remoto en lugar de `o`. Esto es tan común que git efectivamente crea tu remoto llamándolo `origin` cuando haces `git clone` de un repositorio.", + "", + "Desafortunadamente el nombre `origin` completo no entra en nuestra UI (interfaz de usuario), así que usamos `o` para abreviar :(Simplemente recuerda que cuando uses el git real, tu remoto ¡probablemente se llame `origin`!", + "", + "Queda mucho por aprender, así que veámoslo en acción." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Hagamos checkout sobre una rama remota a ver qué pasa." + ], + "afterMarkdowns": [ + "Como ves, git nos puso en el modo detached `HEAD` y no actualizó `o/main` cuando creamos un nuevo commit. Esto ocurre porque `o/main` sólo va a actualizarse cuando el remoto se actualice." + ], + "command": "git checkout o/main; git commit", + "beforeCommand": "git clone" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para completar este nivel, haz commit una vez sobre `main` y otra vez después de checkoutear `o/main`. Esto te va a ayudar a aprender cómo las ramas remotas funcionan distinto, y que sólo se actualizan para reflejar el estado del remoto." ] } } @@ -222,7 +291,7 @@ exports.level = { "", "Agora que vimos o `git clone` em ação, vamos estudar aquilo que realmente mudou.", "", - "A primeira coisa que você pode ter percebido é que um novo ramo chamado `o/master` aparece no nosso repositório local. Esse tipo de ramo é chamado de ramo _remoto_; ramos remotos possuem propriedades especiais pois eles servem a um propósito único.", + "A primeira coisa que você pode ter percebido é que um novo ramo chamado `o/main` aparece no nosso repositório local. Esse tipo de ramo é chamado de ramo _remoto_; ramos remotos possuem propriedades especiais pois eles servem a um propósito único.", "", "Ramos remotos refletem o _estado_ de repositórios remotos (desde a última vez na qual você falou com eles). Eles ajudam a entender as diferenças entre o trabalho local e o trabalho atualmente público -- um passo crítico a ser dado antes de compartilhar seu trabalho com os outros.", "", @@ -240,7 +309,7 @@ exports.level = { "", "* `/`", "", - "Então, se o ramo remoto é chamado `o/master`, o nome do ramo é `master` e o nome do repositório remoto é `o`.", + "Então, se o ramo remoto é chamado `o/main`, o nome do ramo é `main` e o nome do repositório remoto é `o`.", "", "A maioria dos desenvolvedores na verdade chama o repositório remoto principal de `origin`, e não de `o`. Isso é tão comum que o Git define por padrão o nome `origin` para o repositório remoto quando você usa o comando `git clone` para clonar um repositório.", "", @@ -254,12 +323,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Vamos fazer checkout de um ramo remoto e ver o que acontece" + "Vamos fazer checkout de um ramo remoto e ver o que acontece." ], "afterMarkdowns": [ - "Como você pode ver, o Git nos colocou no modo \"Detached HEAD\", e não atualizou o `o/master` quando adicionamos um novo commit. Isso é porque o `o/master` só será atualizado quando o repositório remoto for atualizado." + "Como você pode ver, o Git nos colocou no modo \"Detached HEAD\", e não atualizou o `o/main` quando adicionamos um novo commit. Isso é porque o `o/main` só será atualizado quando o repositório remoto for atualizado." ], - "command": "git checkout o/master; git commit", + "command": "git checkout o/main; git commit", "beforeCommand": "git clone" } }, @@ -267,7 +336,68 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Para completar este nível, commite uma vez em `master`, e outra vez depois de fazer checkout em `o/master`. Isso vai ajudá-lo a sentir como os ramos remotos se comportam de forma diferente, e como eles apenas se atualizam para refletir o estado do repositório remoto." + "Para completar este nível, commite uma vez em `main`, e outra vez depois de fazer checkout em `o/main`. Isso vai ajudá-lo a sentir como os ramos remotos se comportam de forma diferente, e como eles apenas se atualizam para refletir o estado do repositório remoto." + ] + } + } + ] + }, + "gl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Ramas remotas de git", + "", + "Agora que viches `git clone` en acción, mergullémonos no que realmente mudou.", + "", + "O primeiro que notarías é que apareceu unha nova rama no teu repositorio local chamada `o/main`. A este tipo de ramas chámaselle ramas _remotas_. As ramas remotas teñén propiedades especiais porque serven para un propósito específico.", + "", + "As ramas remotas reflexan o _estado_ dos repositorios remotos (como estaban á última vez que falaches con eles). Axúdante a entender as diferencias entre o teu traballo local e o teu traballo que xa está publicado - un paso crítico antes de compartir o teu traballo cos demáis.", + "", + "As ramas remotas teñen a propiedade especial de que cando fas checkout, pasas o modo detached `HEAD`. Git faino a drede porque non podes traballar nesas ramas directamente: tes que traballar nalgún outro lado e despois compartir o teu traballo co remoto (tras o que as túas ramas remotas actualizaranse)." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### ¿Qué é `o/`?", + "", + "Poderías estar a preguntarte qué significa ese `o/` ó principio das ramas remotas. Bueno, as ramas remotas tamén teñen unha convención de nomes obligatoria -- se as amosas co formato:", + "", + "* `/`", + "", + "Entonces, se miras unha rama chamada `o/main`, o nome da rama é `main`, e o nome do remoto é `o`.", + "", + "A maioría dos desenvolvedores chaman `origin` ó seu remoto no lugar de `o`. Esto é tan común que git efectivamente crea o teu remoto chamandoo `origin` cando fas `git clone` dun repositorio.", + "", + "Desafortunadamente o nome `origin` completo non entra na nosa UI, así que empregaremos `o` para acortar: (Sinxelamente recorda que cando uses git na vida real, o teu remote ¡probablemente se chame `origin`!)", + "", + "Hai moito para procesar, así que vexámolo en acción." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Fagamos checkout a unha rama remota a ver qué pasa." + ], + "afterMarkdowns": [ + "Como ves, git púxonos no modo detached `HEAD` e non actualizou `o/mater` cando creamos un novo commit. Esto é porque `o/mater` só vai actualizarse cando o remoto se actualice." + ], + "command": "git checkout o/main; git commit", + "beforeCommand": "git clone" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Para completar este nivel, fai commit unha vez sobre `mater` e despois de facer o checkout a `o/main`. Esto vaite axudar a entender cómo funcionan as ramas remotas, e que só se actualizan para reflexar o estado do remoto." ] } } @@ -283,7 +413,7 @@ exports.level = { "", "現在你已經知道 `git clone` 在幹嘛了,讓我們仔細看看到底發生了什麼事。", "", - "你首先看到的是在你的本地端(local repository)出現了一個新的 branch 叫作 `o/master`,這種型態的 branch 叫作 remote branch (遠端分支),因為特殊的需求,因此 remote branch 有特殊的性質。", + "你首先看到的是在你的本地端(local repository)出現了一個新的 branch 叫作 `o/main`,這種型態的 branch 叫作 remote branch (遠端分支),因為特殊的需求,因此 remote branch 有特殊的性質。", "", "remote branch 反應了 remote repository 的狀態(因為你最後接觸的是這些 remote repository),最重要的是,在你想要分享你的 commit 給其他人時,你必須知道你現在的 commit 跟 remote repository 有哪些不同,而 remote branch 的狀態就是在告訴你這些資訊。", "", @@ -301,7 +431,7 @@ exports.level = { "", "* `/`", "", - "因此,當你看到一個 branch 叫做 `o/master`,就表示這個 branch 叫做 master,而且這個 remote 的名稱叫作 `o`。", + "因此,當你看到一個 branch 叫做 `o/main`,就表示這個 branch 叫做 main,而且這個 remote 的名稱叫作 `o`。", "", "很多程式設計師實際上會把他們的 remote 命名為 `origin`,而不是 `o`,這在 git 是很常見的事情,因為當你使用 `git clone` 時,git 會自動把你的 remote 命名為 `origin`。", "", @@ -318,9 +448,9 @@ exports.level = { "讓我們移動到(checkout)一個 remote branch 並且看一下會發生什麼事情" ], "afterMarkdowns": [ - "就像你看到的, git 讓我們進到 detached `HEAD` 狀態,同時,當我們加入一個新的 commit 時,`o/master` 都沒有更新,這是因為只有當 remote 更新的時候,`o/master` 才會更新。" + "就像你看到的, git 讓我們進到 detached `HEAD` 狀態,同時,當我們加入一個新的 commit 時,`o/main` 都沒有更新,這是因為只有當 remote 更新的時候,`o/main` 才會更新。" ], - "command": "git checkout o/master; git commit", + "command": "git checkout o/main; git commit", "beforeCommand": "git clone" } }, @@ -328,7 +458,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "要完成這一關,先在 master branch 上面做一次 commit,再移動到 `o/master` 上做一次 commit,這有助於我們了解到 remote branch 的不同,它們只會反應 remote 的狀態。" + "要完成這一關,先在 main branch 上面做一次 commit,再移動到 `o/main` 上做一次 commit,這有助於我們了解到 remote branch 的不同,它們只會反應 remote 的狀態。" ] } } @@ -344,9 +474,9 @@ exports.level = { "", "Nun da du `git clone` in Aktion gesehen hast, lass uns tiefer in die Materie eintauchen.", "", - "Das erste, was dir wahrscheinlich aufgefallen ist, ist dass ein neuer Branch in unserem lokalen Repository aufgetaucht ist, namens `o/master`. Diese Art von Branch nennt sich _Remote_ Branch; er hat besondere Eigenschaften, weil er einem bestimmten Zweck dient.", + "Dir ist wahrscheinlich als Erstes aufgefallen, dass ein neuer Branch namens `o/main` in unserem lokalen Repository aufgetaucht ist. Diese Art von Branch nennt sich _Remote_ Branch; er hat besondere Eigenschaften, weil er einem bestimmten Zweck dient.", "", - "Ein Remote Branch bildet den Zustand des entsprechenden Branch in einem entfernten Repository ab (dem Zustand in dem der Branch war, als du das letzte mal das entfernte Repository angesprochen hast). Er hilft dir, den Unterschied zwischen deinem lokalen Branch und dem Gegenstück auf dem Server zu sehen -- eine nötige Information, bevor du deine Arbeit mit anderen teilen kannst.", + "Ein Remote Branch bildet den Zustand des entsprechenden Branch in einem entfernten Repository ab (dem Zustand in dem der Branch war, als du das letzte Mal das entfernte Repository angesprochen hast). Er hilft dir, den Unterschied zwischen deinem lokalen Branch und dem Gegenstück auf dem Server zu sehen -- eine nötige Information, bevor du deine Arbeit mit anderen teilen kannst.", "", "Remote Branches besitzen die besondere Eigenschaft dein Repository in den \"Detached `HEAD`\" Zustand zu versetzen, wenn du sie auscheckst. Git macht das absichtlich so, denn du kannst nicht direkt auf Remote Branches arbeiten; du musst auf Kopien von ihnen arbeiten und deine Änderungen von dort auf den entfernten Server schieben (wonach der Remote Branch dann auch bei dir aktualisiert wird)." ] @@ -362,11 +492,11 @@ exports.level = { "", "* `/`", "", - "Wenn du also einen Remote Branch namens `o/master` hast, ist es eine Abbildung des Branches `master` auf dem Server, der in deinem Repository als `o` bekannt ist.", + "Wenn du also einen Remote Branch namens `o/main` hast, ist es eine Abbildung des Branches `main` auf dem Server, der in deinem Repository als `o` bekannt ist.", "", - "Die meisten Entwickler nennen das Haupt-Remote tatsächlich `origin` und nicht `o`. Das ist so verbreitet, dass Git den entfernten Server von dem man ein `git clone` macht tatsächlich als `origin` im Clone speichert.", + "Die meisten Entwickler nennen das Haupt-Remote eigentlich `origin` und nicht `o`. Das ist so verbreitet, dass Git den entfernten Server, von dem man ein `git clone` macht, standardmäßig als `origin` im Clone speichert.", "", - "Leider passt der ganze Name, `origin`, nicht in unsere Darstellung, deshalb benutzen wir hier kurz `o`. :( Merk dir einfach: wenn du echtes Git benutzt werden die Remotes meistens `origin` heißen!", + "Leider passt der ganze Name, `origin`, nicht in unsere Darstellung, deshalb benutzen wir hier kurz `o`. :( Merk dir einfach: wenn du echtes Git benutzt, werden die Remotes meistens `origin` heißen!", "", "So, das war eine Menge zu verdauen, schauen wir uns das in Aktion an." ] @@ -376,12 +506,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Checken wir mal einen Remote Branch aus und schauen was passiert" + "Checken wir mal einen Remote Branch aus und schauen was passiert." ], "afterMarkdowns": [ - "Wie du siehst setzt uns Git in den \"Detached `HEAD`\" Modus und aktualisiert dann nach dem Commit nicht den Branch `o/master`. Das liegt daran, dass der Remote Branch nur aktualisiert wird, wenn sich der entsprechende Branch auf dem Remote verändert." + "Wie du siehst setzt uns Git in den \"Detached `HEAD`\" Modus und aktualisiert dann nach dem Commit nicht den Branch `o/main`. Das liegt daran, dass der Remote Branch nur aktualisiert wird, wenn sich der entsprechende Branch auf dem Remote verändert." ], - "command": "git checkout o/master; git commit", + "command": "git checkout o/main; git commit", "beforeCommand": "git clone" } }, @@ -389,7 +519,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Um diesen Level zu bewältigen musst du einen Commit in `master` machen und einen nachdem du `o/master` ausgecheckt hast. Das illustriert noch einmal wie sich Branches und Remote Branches unterschiedlich verhalten und dass letztere sich nur verändern, wenn sich ihr Zustand auf dem entfernten Server ändert." + "Um diesen Level zu bewältigen musst du einen Commit in `main` machen und einen nachdem du `o/main` ausgecheckt hast. Das illustriert noch einmal wie sich Branches und Remote Branches unterschiedlich verhalten und dass letztere sich nur verändern, wenn sich ihr Zustand auf dem entfernten Server ändert." ] } } @@ -405,11 +535,11 @@ exports.level = { "", "既然你已经看过 `git clone` 命令了,咱们深入地看一下发生了什么。", "", - "你可能注意到的第一个事就是在我们的本地仓库多了一个名为 `o/master` 的分支, 这种类型的分支就叫**远程**分支。由于远程分支的特性导致其拥有一些特殊属性。", + "你可能注意到的第一个事就是在我们的本地仓库多了一个名为 `o/main` 的分支, 这种类型的分支就叫**远程**分支。由于远程分支的特性导致其拥有一些特殊属性。", "", "远程分支反映了远程仓库(在你上次和它通信时)的**状态**。这会有助于你理解本地的工作与公共工作的差别 —— 这是你与别人分享工作成果前至关重要的一步.", "", - "远程分得有一个特别的属性,在你检出时自动进入分离 HEAD 状态。Git 这么做是出于不能直接在这些分支上进行操作的原因, 你必须在别的地方完成你的工作, (更新了远程分支之后)再用远程分享你的工作成果。" + "远程分支有一个特别的属性,在你检出时自动进入分离 HEAD 状态。Git 这么做是出于不能直接在这些分支上进行操作的原因, 你必须在别的地方完成你的工作, (更新了远程分支之后)再用远程分享你的工作成果。" ] } }, @@ -423,7 +553,7 @@ exports.level = { "", "* `/`", "", - "因此,如果你看到一个名为 `o/master` 的分支,那么这个分支就叫 `master`,远程仓库的名称就是 `o`。", + "因此,如果你看到一个名为 `o/main` 的分支,那么这个分支就叫 `main`,远程仓库的名称就是 `o`。", "", "大多数的开发人员会将它们主要的远程仓库命名为 `origin`,并不是 `o`。这是因为当你用 `git clone` 某个仓库时,Git 已经帮你把远程仓库的名称设置为 `origin` 了", "", @@ -440,9 +570,9 @@ exports.level = { "如果检出远程分支会怎么样呢?" ], "afterMarkdowns": [ - "正如你所见,Git 变成了分离 HEAD 状态,当添加新的提交时 `o/master` 也不会更新。这是因为 `o/master` 只有在远程仓库中相应的分支更新了以后才会更新。" + "正如你所见,Git 变成了分离 HEAD 状态,当添加新的提交时 `o/main` 也不会更新。这是因为 `o/main` 只有在远程仓库中相应的分支更新了以后才会更新。" ], - "command": "git checkout o/master; git commit", + "command": "git checkout o/main; git commit", "beforeCommand": "git clone" } }, @@ -450,7 +580,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "要通过本关,在 `master` 分支上做一次提交;然后检出 `o/master`,再做一提交。这有助于你理解远程分支的不同,他们的更新只是反映了远程的状态。" + "要通过本关,在 `main` 分支上做一次提交;然后检出 `o/main`,再做一提交。这有助于你理解远程分支的不同,他们的更新只是反映了远程的状态。" ] } } @@ -484,7 +614,7 @@ exports.level = { "", "* `<リモート名>/<ブランチ名>`", "", - "これに基づいて、`o/master`と名付けられたブランチを見てみると、`master`はブランチの名前、`o`はリモートの名前であることが分かります。", + "これに基づいて、`o/main`と名付けられたブランチを見てみると、`main`はブランチの名前、`o`はリモートの名前であることが分かります。", "", "多くの開発者は、実際にはメインのリモート名として`o`ではなく`origin`を使います。これは一般的には、Gitが`git clone`した時に`origin`という名前をリモートに付与するためです。", "", @@ -501,9 +631,9 @@ exports.level = { "リモートブランチをチェックアウトすると何が起こるかを見てみましょう" ], "afterMarkdowns": [ - "見ていた通り、`o/master`に移ってから新しいコミットをしても`HEAD`が分離状態になり`o/master`は更新されていません。これは、`o/master`がリモートの更新時のみ更新されるからです。" + "見ていた通り、`o/main`に移ってから新しいコミットをしても`HEAD`が分離状態になり`o/main`は更新されていません。これは、`o/main`がリモートの更新時のみ更新されるからです。" ], - "command": "git checkout o/master; git commit", + "command": "git checkout o/main; git commit", "beforeCommand": "git clone" } }, @@ -511,7 +641,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "このレベルを終えるには、まずコミットを`master`に一回行い、その後`o/master`にチェックアウトしてからもう一度コミットをします。これは、リモートブランチがどれほど違った動きをするか、そしてリモートブランチがリモートの状態を反映する時しか更新されないことを理解するのに役立つでしょう。" + "このレベルを終えるには、まずコミットを`main`に一回行い、その後`o/main`にチェックアウトしてからもう一度コミットをします。これは、リモートブランチがどれほど違った動きをするか、そしてリモートブランチがリモートの状態を反映する時しか更新されないことを理解するのに役立つでしょう。" ] } } @@ -527,7 +657,7 @@ exports.level = { "", "Теперь, когда вы уже увидели `git clone` в действии, давайте углубимся в детали и посмотрим что же на самом деле изменилось.", "", - "Во-первых, вы должны были заметить, что у нас в локальном репозитории появилась новая ветка с именем `o/master`. Такой тип ветки называется _удалённой_ веткой. Поскольку удалённые ветки играют важную и уникальную роль, они обладают рядом специальных свойств.", + "Во-первых, вы должны были заметить, что у нас в локальном репозитории появилась новая ветка с именем `o/main`. Такой тип ветки называется _удалённой_ веткой. Поскольку удалённые ветки играют важную и уникальную роль, они обладают рядом специальных свойств.", "", "Удалённые ветки отражают _состояние_ удалённых репозиториев (с того момента, как вы обращались к этим удалённым репозиториям в последний раз). Они позволяют вам отслеживать и видеть разницу между вашими локальными наработками и тем, что было сделано другими участниками - важный шаг, который необходимо делать, прежде чем делиться своими наработками с другими.", "", @@ -545,7 +675,7 @@ exports.level = { "", "* `<удалённый репозиторий>/<имя ветки>`", "", - "Следовательно, если вы взглянете на имя ветки `o/master`, то здесь `master` - это имя ветки, а `o` - это имя удалённого репозитория.", + "Следовательно, если вы взглянете на имя ветки `o/main`, то здесь `main` - это имя ветки, а `o` - это имя удалённого репозитория.", "", "Большинство разработчиков именуют свои главные удалённые репозитории не как `o`, а как `origin`. Также общепринятым является именование удалённого репозитория как `origin`, когда вы клонируете репозиторий командой `git clone`.", "", @@ -562,9 +692,9 @@ exports.level = { "Давайте извлечём (check out) удалённую ветку и посмотрим что произойдёт" ], "afterMarkdowns": [ - "Как вы можете видеть, git отделил (detached) `HEAD` и не обновил `o/master`, когда мы добавили новый коммит. Всё потому, что `o/master` обновится тогда и только тогда, когда обновится сам удалённый репозиторий." + "Как вы можете видеть, git отделил (detached) `HEAD` и не обновил `o/main`, когда мы добавили новый коммит. Всё потому, что `o/main` обновится тогда и только тогда, когда обновится сам удалённый репозиторий." ], - "command": "git checkout o/master; git commit", + "command": "git checkout o/main; git commit", "beforeCommand": "git clone" } }, @@ -572,7 +702,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Для завершения уровня выполните коммит единожды на `master`, а затем на `o/master` (предварительно переключившись на эту ветку). Это наглядно продемонстрирует поведение удалённых веток, а также покажет, как изменения влияют на состояние удалённых репозиториев." + "Для завершения уровня выполните коммит единожды на `main`, а затем на `o/main` (предварительно переключившись на эту ветку). Это наглядно продемонстрирует поведение удалённых веток, а также покажет, как изменения влияют на состояние удалённых репозиториев." ] } } @@ -588,7 +718,7 @@ exports.level = { "", "이제 `git clone`을 직접 확인 해 보셨습니다. 이제 무엇이 변했는지 살펴 봅시다.", "", - "가장 먼저 알아차릴만한 변화는 우리의 로컬 저장소에 `o/master`라고하는 새 브랜치가 생긴겁니다. 이런 종류의 브랜치는 _원격_브랜치라고 불립니다; 원격 브랜치는 특정한 목적을 제공하기 때문에 특별한 속성들이 있습니다.", + "가장 먼저 알아차릴만한 변화는 우리의 로컬 저장소에 `o/main`라고하는 새 브랜치가 생긴겁니다. 이런 종류의 브랜치는 _원격_브랜치라고 불립니다; 원격 브랜치는 특정한 목적을 제공하기 때문에 특별한 속성들이 있습니다.", "", "원격 브랜치는 원격 저장소의 _상태_를 반영합니다(가장 최근 원격 원격저장소와 작업을 했을때를 기준으로). 원격 브랜치는 로컬에서의 작업과 공개적으로 되고있는 작업의 차이를 이해하는데 도와줍니다 -- 다른 사람들과 작업을 공유하기전에 반드시해야할 과정이죠.", "", @@ -606,7 +736,7 @@ exports.level = { "", "* `/`", "", - "이런 이유로, 만약 `o/master`라는 이름의 브랜치를 보게되면, 브랜치의 이름은 `master`이고 원격 저장소의 이름은 `o`인겁니다.", + "이런 이유로, 만약 `o/main`라는 이름의 브랜치를 보게되면, 브랜치의 이름은 `main`이고 원격 저장소의 이름은 `o`인겁니다.", "", "대부분의 개발자들은 자신의 주 원격 저장소를 `o`가 아닌 `origin`이라고 짓습니다. 사실 보통 다 이렇게 쓰기 때문에 git은 저장소를 `git clone`하게 되면 원격 저장소의 이름을 `origin`이라고 자동으로 설정해놓습니다.", "", @@ -623,9 +753,9 @@ exports.level = { "원격 브랜치를 체크아웃하고 무엇이 일어나는지 확인해 봅시다" ], "afterMarkdowns": [ - "보이는것 처럼, git은 우리를 분리된 `HEAD` 모드로 만들고 새로운 커밋을 추가해도 `o/master`를 갱신하지 않습니다. 이것은 `o/master`가 원격 저장소가 갱신될때만 갱신되기 때문입니다." + "보이는것 처럼, git은 우리를 분리된 `HEAD` 모드로 만들고 새로운 커밋을 추가해도 `o/main`를 갱신하지 않습니다. 이것은 `o/main`가 원격 저장소가 갱신될때만 갱신되기 때문입니다." ], - "command": "git checkout o/master; git commit", + "command": "git checkout o/main; git commit", "beforeCommand": "git clone" } }, @@ -633,7 +763,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "다음 레벨로 가기 위해서는 `master`에서 한번 커밋하고 `o/master`를 체크아웃 하고 다시 한번 커밋을 하세요. 이를 통해서 원격 브랜치가 어떻게 다르게 작동하는지 알아보고, 원격 브랜치는 원격 저장소의 상태를 반영하기만 한다는것을 이해해 봅시다." + "다음 레벨로 가기 위해서는 `main`에서 한번 커밋하고 `o/main`를 체크아웃 하고 다시 한번 커밋을 하세요. 이를 통해서 원격 브랜치가 어떻게 다르게 작동하는지 알아보고, 원격 브랜치는 원격 저장소의 상태를 반영하기만 한다는것을 이해해 봅시다." ] } } @@ -649,7 +779,7 @@ exports.level = { "", "Тепер, коли ти познайомився з `git clone` в дії, розгляньмо деталі й подивімося, що дійсно змінилося.", "", - "Перше, що ти міг помітити -- це те, що з’явився новий бранч з назвою `o/master`. Такі гілки називаються _віддаленими_ (remote); віддалені гілки в гіт відіграють в певному сенсі унікальну роль, тому в них є деякі спеціальні властивості, непритаманні іншим гілкам.", + "Перше, що ти міг помітити -- це те, що з’явився новий бранч з назвою `o/main`. Такі гілки називаються _віддаленими_ (remote); віддалені гілки в гіт відіграють в певному сенсі унікальну роль, тому в них є деякі спеціальні властивості, непритаманні іншим гілкам.", "", "Віддалені гілки відображають _стан_ віддалених репозиторіїв (точніше, стан віддаленого репо на момент останньої синхронізації). Вони дозволяють відрізняти та відслідковувати локальні зміни та зміни інших учасників, що є дуже важливим для успішної синхронізації роботи між різними репозиторіями.", "", @@ -667,7 +797,7 @@ exports.level = { "", "* `<ім’я віддаленого репо>/<ім’я гілки>`", "", - "Отже, якщо розглянути гілку з назвою `o/master`, то ім’я гілки -- це `master` а ім’я віддаленого репозиторію -- це `o`.", + "Отже, якщо розглянути гілку з назвою `o/main`, то ім’я гілки -- це `main` а ім’я віддаленого репозиторію -- це `o`.", "", "Більшість розробників насправді називають ім’я головного віддаленого репозиторію `origin` (початок), а не `o`. Це настільки поширена практика, що гіт автоматично називає віддалений репозиторій `origin` коли ти його клонуєш.", "", @@ -684,9 +814,9 @@ exports.level = { "Зробімо checkout віддаленої гілки й подивімось, що буде" ], "afterMarkdowns": [ - "Як бачиш, git перейшов в стан `detached HEAD` і не оновив `o/master` коли ми зробили новий коміт. Це тому, що `o/master` буде оновлено лише тоді, коли буде оновлено віддалений репозиторій." + "Як бачиш, git перейшов в стан `detached HEAD` і не оновив `o/main` коли ми зробили новий коміт. Це тому, що `o/main` буде оновлено лише тоді, коли буде оновлено віддалений репозиторій." ], - "command": "git checkout o/master; git commit", + "command": "git checkout o/main; git commit", "beforeCommand": "git clone" } }, @@ -694,7 +824,129 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Щоб пройти цей рівень, зроби один коміт в `master`, а потім переключись в `o/master` і закомітся ще раз. Це наглядно продемонструє поведінку віддалених гілок, а також покаже як зміни впливають на стан віддаленого репозиторію." + "Щоб пройти цей рівень, зроби один коміт в `main`, а потім переключись в `o/main` і закомітся ще раз. Це наглядно продемонструє поведінку віддалених гілок, а також покаже як зміни впливають на стан віддаленого репозиторію." + ] + } + } + ] + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Nhánh Git từ xa", + "", + "Giờ bạn đã thấy cách thức hoạt động của `git clone`, cùng xem xét kỹ hơn những gì đã xảy ra.", + "", + "Điều đầu tiên mà có thể bạn để ý là một nhánh mới xuất hiện trong kho chứa địa phương của ta là `o/main`. Loại nhánh này được gọi là nhánh _từ xa_ (_remote_) ; nhánh từ xa có những thuộc tính đặc biệt vì chúng phục vụ những mục đích duy nhất.", + "", + "Nhánh từ xa phản ánh _trạng thái_ (_state_) của kho chứa từ xa (kể từ lần cuối cùng bạn tương tác với kho chứa từ xa). Chúng giúp bạn hiểu về sự khác biệt giữa công tác trên kho chứa cục bộ với kho chứa từ xa -- một bước quan trọng trước khi chia sẻ công việc của bạn với người khác.", + "", + "Nhánh từ xa có một thuộc tính đặc biệt đó là khi bạn chuyển sang chúng bạn sẽ vào trạng thái tách rời `HEAD`. Git chủ tâm làm việc này vì bạn không thể công tác trực tiếp trên chúng; bạn phải công tác ở nơi khác và chia sẻ thành quả lên kho chứa từ xa (sau đó nhánh từ xa sẽ được cập nhật)." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "###`o/` là gì vậy?", + "", + "Có thể bạn sẽ thắc mắc về ký tự `o/` ở đầu tên nhánh từ xa có ý nghĩa gì. Chà, tên nhánh từ xa cũng có (thiết yếu) quy tắc đặt tên -- chúng được hiển thị dưới dạng:", + "", + "* `/`", + "", + "Do đó, ở trong `o/main` thì `main` là tên nhánh còn `o` là tên kho chứa từ xa.", + "", + "Thực tế thì hầu hết các nhà phát triển đặt tên kho chứa từ xa là `origin` chứ không phải `o`. Nó trở thành thông lệ đến nỗi Git đặt tên `origin` cho kho chứa từ xa khi bạn dùng `git clone` để sao chép một kho chứa.", + "", + "Đáng tiêc là `origin` không khớp trong giao diện của chúng tôi, nên chúng tôi đành phải viết tắt là `o` :( Nhưng hãy nhớ rằng khi dùng git thật sự thì chắc hẳn tên của kho chứa từ xa sẽ là `origin`!", + "", + "Lý thuyết hơi nhiều rồi, đi vào thực hành thôi." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Hãy thử chuyển sang nhánh từ xa xem điểu gì xảy ra." + ], + "afterMarkdowns": [ + "Như bạn thấy, git đưa ta vào trạng thái `HEAD` và không cập nhật nhánh `o/main` khi ta thêm một commit. Đó là bởi vì `o/main` chỉ cập nhật khi kho chứa từ xa được cập nhật." + ], + "command": "git checkout o/main; git commit", + "beforeCommand": "git clone" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Để hoàn thành cấp độ này, commit một lần trên `main` và một lần nữa sau khi chuyển sang `o/main`. Điều nãy sẽ giúp ta hiểu cách nhánh từ xa hành xử, chúng chỉ cập nhật để phản ánh trạng thái của kho chứa từ xa." + ] + } + } + ] + }, + "sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Oddaljeni Branchi", + "", + "Sedaj ko smo videli `git clone` v praksi se poglobimo v dejanske spremembe.", + "", + "Prva stvar, ki si jo morda opazil je, da se je pojavil nov branch na našem lokalnem repotu imenovan `o/main`. Temu tipu brancha pravimo _oddaljen_ (remote) branch; oddaljeni branchi imajo posebne lastnosti, ker služijo določenim namenom.", + "", + "Oddaljeni branchi odražajo _stanje_ oddaljenega repozitorija (od kar si nazadnje komuniciral z oddaljenim repotom). To ti morda pomaga razumeti razliko med tvojim lokalnim delom in delom, ki je javno -- ključni korak, preden deliš svoje delo z ostalimi.", + "", + "Oddaljeni branchi imajo posebno lastnost, da ko jih checkoutaš, si postavljen v stanje z ločenim `HEAD-om`. Git naredi to zanalašč, ker ne moreš delati neposredno na teh branchih; moreš delati drugje in nato deliti svoje delo z oddaljenim repotom (po tem bodo oddaljeni branchi bili posodobljeni)." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Kaj je `o/`?", + "", + "Morda se sprašuješ, kaj je ta `o/` spredaj pred oddaljenmi branchi. Tudi oddaljeni branchi imajo (zahtevano) pravilo za poimenovanje -- predstavljeni so v sledečem formatu:", + "", + "* `/`", + "", + "Posledično, če pogledamo branch poimenovan `o/main`, je ime brancha `main`, ime oddaljenega repota pa `o`.", + "", + "Večina razvijalcev v bistvu poimenuje njihov glavni oddaljeni repozitorij `origin`, ne `o`. To je takoj pogosto, da git ubistvu nastavi tvoj oddaljen repo z imenom `origin` ko izvedeš `git clone` nad repozitorijem.", + "", + "Nažalost polno ime `origin` ne paše v naš prikaz, zato uporabljamo `o` kot bližnjico :( Samo zapomni si, ko uporabljaš pravi git, bo tvoj oddaljen repo verjetno poimenovan `origin`!", + "", + "To je kar veliko za razumeti, zato si poglejmo stvar v akciji." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Checkoutajmo oddaljen branch in poglejmo kaj se zgodi." + ], + "afterMarkdowns": [ + "Kot lahko vidiš, nas git postavi v stanje ločenega `HEAD-a` in ne posodobi `o/main`, ko dodamo nov commit. To je zato, ker se bo `o/main` posodobil šele, ko se bo posodobil oddaljen repo." + ], + "command": "git checkout o/main; git commit", + "beforeCommand": "git clone" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Za dokončanje te stopnje, commitaj enkrat iz `main` in enkrat, ko checkoutaš `o/main`. To ti bo pomagalo osvojiti, kako se oddaljeni branchi obnašajo drugače in se posodobijo le da odražajo stanje na oddaljenem repozitoriju." ] } } diff --git a/src/levels/remote/sourceNothing.js b/src/levels/remote/sourceNothing.js index 40899640..09fbea3e 100644 --- a/src/levels/remote/sourceNothing.js +++ b/src/levels/remote/sourceNothing.js @@ -1,4 +1,9 @@ exports.level = { + "compareAllBranchesAndEnforceBranchCleanup": true, + "disabledMap": { + "git branch": true, + "git checkout": true + }, "goalTreeString": "{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\"},\"o/master\":{\"target\":\"C1\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null},\"bar\":{\"target\":\"C1\",\"id\":\"bar\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", "solutionCommand": "git push origin :foo;git fetch origin :bar", "startTree": "{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\"},\"o/master\":{\"target\":\"C1\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null},\"o/foo\":{\"target\":\"C1\",\"id\":\"o/foo\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\",\"remoteTrackingBranchID\":null},\"foo\":{\"target\":\"C1\",\"id\":\"foo\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", @@ -7,26 +12,34 @@ exports.level = { "zh_CN": "没有 source 的 source", "zh_TW": "沒有 source", "es_AR": "Origen de nada", + "es_ES": "Origen de nada", "pt_BR": "Origem vazia", + "gl" : "Orixen de nada", "de_DE": "Die Quelle des Nichts", "ja" : "無のsource", "fr_FR": "Source de rien du tout", "ru_RU": "Пустой источник", "ko" : "Source가 없다", - "uk" : "Нема джерела" + "uk" : "Нема джерела", + "vi" : "Không có nguồn", + "sl_SI": "Izvor Ničesar" }, "hint": { "en_US": "The branch command is disabled for this level so you'll have to use fetch!", "zh_CN": "本关的 branch 命令被禁用了,你只能用 fetch!", "zh_TW": "在本關卡中,不允許使用 branch 指令,因此你只能使用 fetch!", "es_AR": "El comando branch está deshabilitado para este nivel, así que ¡vas a tener que usar fetch!", + "es_ES": "El comando branch está deshabilitado para este nivel, así que ¡vas a tener que usar fetch!", "pt_BR": "O comando branch está desabilitado para este nível, então você terá de usar o fetch!", + "gl" : "O comando branch está deshabilitado para este nivel, entón terás que empregar o comando fetch!", "de_DE": "Der branch Befehl ist für diesen Level inaktiv, du musst also fetch benutzen", "ja" : "このレベルではbranchコマンドが無効になっているのでfetchを使うしかない!", "fr_FR": "La commande branch est désactivée pour ce niveau, vous devrez donc utiliser fetch !", "ru_RU": "Команда branch недоступна на этом упражнении, пользуйтесь командой fetch!", "ko" : "branch 명령이 비활성화 되어있습니다. fetch를 사용해야 되요!", "uk" : "Команда branch недоступна на цьому уроці, користуйся командою fetch!", + "vi" : "Lệnh branch đã bị vô hiệu hóa ở cấp độ này nên bạn sẽ phải dùng fetch!", + "sl_SI": "Ukaz za branchanje je v tej stopnji onemogočen, zato boš moral uporabiti fetch!" }, "startDialog": { "en_US": { @@ -56,14 +69,14 @@ exports.level = { "There, we successfully deleted the `foo` branch on remote by pushing the concept of \"nothing\" to it. That kinda makes sense..." ], "command": "git push origin :foo", - "beforeCommand": "git clone; git push origin master:foo" + "beforeCommand": "git clone; git push origin main:foo" } }, { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Finally, fetching \"nothing\" to a place locally actually makes a new branch" + "Finally, fetching \"nothing\" to a place locally actually makes a new branch." ], "afterMarkdowns": [ "Very odd / bizarre, but whatever. That's git for you!" @@ -109,7 +122,7 @@ exports.level = { "Ici, nous avons brillamment supprimé la branche `foo` du dépôt distant en lui envoyant le concept de \"rien\". Cela paraît à peu près logique..." ], "command": "git push origin :foo", - "beforeCommand": "git clone; git push origin master:foo" + "beforeCommand": "git clone; git push origin main:foo" } }, { @@ -143,7 +156,7 @@ exports.level = { "markdowns": [ "### Rarezas de ``", "", - "Git abusa del parámetro `` de dos extrañas maneras. Estos dos abusos vienen del hecho de que tecnicamente podés especificar \"la nada\" como un `origen` válido tanto para git push como para git fetch. El modo de especificar la nada es a través de un parámetro vacío:", + "Git abusa del parámetro `` de dos extrañas maneras. Estos dos abusos vienen del hecho de que técnicamente podés especificar \"la nada\" como un `origen` válido tanto para git push como para git fetch. El modo de especificar la nada es a través de un parámetro vacío:", "", "* `git push origin :side`", "* `git fetch origin :bugFix`", @@ -162,14 +175,14 @@ exports.level = { "Ahí está, borramos la rama `foo` exitosamente del remoto pusheándole el concepto de \"nada\". Tiene algo de sentido..." ], "command": "git push origin :foo", - "beforeCommand": "git clone; git push origin master:foo" + "beforeCommand": "git clone; git push origin main:foo" } }, { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Finalmente, fetchear \"nada\" a un lugar local en realidad crea una nueva rama" + "Finalmente, fetchear \"nada\" a un lugar local en realidad crea una nueva rama." ], "afterMarkdowns": [ "Bastante bizarro, pero, meh, da igual. Así es git." @@ -188,6 +201,59 @@ exports.level = { } ] }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Rarezas de ``", + "", + "Git abusa del parámetro `` de dos extrañas maneras. Estos dos abusos vienen del hecho de que técnicamente puedes especificar \"la nada\" como un `origen` válido tanto para git push como para git fetch. El modo de especificar la nada es a través de un parámetro vacío:", + "", + "* `git push origin :side`", + "* `git fetch origin :bugFix`", + "", + "Veamos qué hacen estos..." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "¿Qué hace el hacer push de \"nada\" a una rama remota? ¡La elimina!" + ], + "afterMarkdowns": [ + "Ahí está, eliminamos la rama `foo` exitosamente del remoto haciendo push con \"nada\". Tiene algo de sentido..." + ], + "command": "git push origin :foo", + "beforeCommand": "git clone; git push origin main:foo" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Finalmente, hacer fetch de \"nada\" a un lugar local en realidad crea una nueva rama." + ], + "afterMarkdowns": [ + "Bastante extraño, pero bueno, da igual. Así es git." + ], + "command": "git fetch origin :bar", + "beforeCommand": "git clone" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Este es un nivel breve: simplemente elimina una rama remota y crea una nueva usando `git fetch` para completarlo." + ] + } + } + ] + }, "pt_BR": { "childViews": [ { @@ -215,14 +281,14 @@ exports.level = { "Aqui, excluímos com sucesso o ramo `foo` do repositório remoto por meio de um push de \"coisa nenhuma\" direcionado a ele. Até que faz sentido..." ], "command": "git push origin :foo", - "beforeCommand": "git clone; git push origin master:foo" + "beforeCommand": "git clone; git push origin main:foo" } }, { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Finalmente, fazer um fetch de \"coisa nenhuma\" para uma referência local cria um novo ramo" + "Finalmente, fazer um fetch de \"coisa nenhuma\" para uma referência local cria um novo ramo." ], "afterMarkdowns": [ "Bastante estranho / bizarro, mas de qualquer forma. É assim que o Git é!" @@ -241,6 +307,59 @@ exports.level = { } ] }, + "gl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Rarezas do ``", + "", + "Git abusa do parámetro `` de dúas maneiras extranas. Estos dous abusos veñen do feito de que técnicamente podes especificar \"á nada\" como un `orixe` válido tanto para git push como para git fetch. O modo de especificar a nada é a través dun parámetro vacío:", + "", + "* `git push origin :side`", + "* `git fetch origin :bugFix`", + "", + "Vexamos qué fan..." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "¿Qué fai cando se empurra a \"nada\" a unha rama remota? ¡Eliminaa!" + ], + "afterMarkdowns": [ + "Ahí está, borramos a rama `foo` exitosamente do remoto empurrando o concepto da \"nada\". Ten algo de sentido..." + ], + "command": "git push origin :foo", + "beforeCommand": "git clone; git push origin main:foo" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Finalmente, descargar a \"nada\" a un lugar local na realidade crea unha nova rama." + ], + "afterMarkdowns": [ + "Bastante bizarro, pero, meh, da igual. Así é git." + ], + "command": "git fetch origin :bar", + "beforeCommand": "git clone" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Este é un nivel rápido: simplemente borra unha rama remota e crea unha nova empregando `git fetch` para completalo." + ] + } + } + ] + }, "zh_TW": { "childViews": [ { @@ -268,7 +387,7 @@ exports.level = { "看吧,我們藉由把 source \"留空\",成功用 `push` 刪除了 `foo` branch,這合理吧..." ], "command": "git push origin :foo", - "beforeCommand": "git clone; git push origin master:foo" + "beforeCommand": "git clone; git push origin main:foo" } }, { @@ -321,7 +440,7 @@ exports.level = { "就是这样子, 我们通过给 push 传空值 source,成功删除了远程仓库中的 `foo` 分支, 这真有意思..." ], "command": "git push origin :foo", - "beforeCommand": "git clone; git push origin master:foo" + "beforeCommand": "git clone; git push origin main:foo" } }, { @@ -355,7 +474,7 @@ exports.level = { "markdowns": [ "### Die Eigentümlichkeiten von ``", "", - "Git \"missbraucht\" den ``-Parameter in zwei Fällen. Diese rühren daher, dass man technisch gesehen \"nichts\" als gültige `` sowohl für `git push` als auch für `git fetch` angeben kann. Das macht man so:", + "Git \"missbraucht\" den ``-Parameter in zwei Fällen. Dies rührt daher, dass man technisch gesehen \"nichts\" als gültige `` sowohl für `git push` als auch für `git fetch` angeben kann. Das macht man so:", "", "* `git push origin :side`", "* `git fetch origin :bugFix`", @@ -374,7 +493,7 @@ exports.level = { "Und schon haben wir `foo` erfolgreich auf dem Remote gelöscht, weil wir \"Leere\" darauf geschoben haben. Ist auf seine Weise irgendwie logisch ..." ], "command": "git push origin :foo", - "beforeCommand": "git clone; git push origin master:foo" + "beforeCommand": "git clone; git push origin main:foo" } }, { @@ -427,7 +546,7 @@ exports.level = { "Как видите, мы удалили ветку `foo` в удаленном репозитории, попытавшить протолкнуть(git push) в неё \"ничего\"." ], "command": "git push origin :foo", - "beforeCommand": "git clone; git push origin master:foo" + "beforeCommand": "git clone; git push origin main:foo" } }, { @@ -480,7 +599,7 @@ exports.level = { "됬습니다, 원격 저장소의 `foo`브랜치를 성공적으로 삭제했습니다. \"없음\"을 push한다는것이 이것을 이뤘습니다. 흠 말이 되는것 같네요 null을 push했어요..." ], "command": "git push origin :foo", - "beforeCommand": "git clone; git push origin master:foo" + "beforeCommand": "git clone; git push origin main:foo" } }, { @@ -533,7 +652,7 @@ exports.level = { "Ось, ми успішно видалили гілку `foo` на віддаленому сервері, запушивши в неї \"ніщо\". Ну, ніби все правильно..." ], "command": "git push origin :foo", - "beforeCommand": "git clone; git push origin master:foo" + "beforeCommand": "git clone; git push origin main:foo" } }, { @@ -558,6 +677,112 @@ exports.level = { } } ] + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Sự kỳ quặc của ``", + "", + "Git lợi dụng tham số `` theo 2 cách khá dị.Hai cách lợi dụng này bắt nguồn từ thục tế là bạn có thể \"không chỉ định\" `nguồn` cho cả git push và git fetch. Bạn có thể làm điều này bằng cách để trống tham số như sau:", + "", + "* `git push origin :side`", + "* `git fetch origin :bugFix`", + "", + "Hãy xem thử 2 câu lệnh này làm việc gì..." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Nếu ta đẩy \"không gì cả\" lên một nhánh từ xa thì nó sẽ làm gì? Nó xóa nhánh đó!" + ], + "afterMarkdowns": [ + "Đó, ta đã xóa thành công nhánh `foo` trên kho chứa từ xa bằng cách đẩy \"không gì cả\" lên nó. Khá là hợp lý..." + ], + "command": "git push origin :foo", + "beforeCommand": "git clone; git push origin main:foo" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Cuối cùng, nạp \"không gì cả\" vào một kho chứa cục bộ thực tế sẽ tạo ra một nhánh mới" + ], + "afterMarkdowns": [ + "Khá là quái và dị. Nhưng mà dó là những gì git làm!" + ], + "command": "git fetch origin :bar", + "beforeCommand": "git clone" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Ở cấp độ đơn giản này -- bạn chỉ cần xóa một nhánh từ xa và tạo ra một nhánh mới với `git fetch` để hoàn thành!" + ] + } + } + ] + }, + "sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Čudnosti ``", + "", + "Git zlorablja `` parameter na dva čudna načina. Te dve zlorabi nastaneta iz dejstva, da lahko tehnično določiš \"nič\" kot veljaven `izvor` za git push in git fetch. Način, da določiš nič je z uporabo praznega argumenta:", + "", + "* `git push origin :side`", + "* `git fetch origin :bugFix`", + "", + "Poglejmo, kaj to naredi ..." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Kaj naredi pushanje \"ničesar\" na oddaljen branch? Izbriše ga!" + ], + "afterMarkdowns": [ + "Tako, uspešno smo izbrisali `foo` branch na oddaljenem repotu s konceptom pushanja \"ničesar\" nanj. To ima nekako smisel ..." + ], + "command": "git push origin :foo", + "beforeCommand": "git clone; git push origin main:foo" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "In končno, fetchanje \"ničesar\" lokalno dejansko naredi nov branch." + ], + "afterMarkdowns": [ + "Zelo čudno / bizarno, ampak kakorkoli. Tak je git!" + ], + "command": "git fetch origin :bar", + "beforeCommand": "git clone" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "To je hitra stopnja -- samo izbriši en oddaljen branch in naredi novega z `git fetch`, da zaključiš!" + ] + } + } + ] } } }; diff --git a/src/levels/remote/tracking.js b/src/levels/remote/tracking.js index 8892cd6b..a959f943 100644 --- a/src/levels/remote/tracking.js +++ b/src/levels/remote/tracking.js @@ -1,32 +1,40 @@ exports.level = { "goalTreeString": "%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C1%22%2C%22id%22%3A%22master%22%2C%22remoteTrackingBranchID%22%3A%22o/master%22%7D%2C%22o/master%22%3A%7B%22target%22%3A%22C3%27%22%2C%22id%22%3A%22o/master%22%2C%22remoteTrackingBranchID%22%3Anull%7D%2C%22side%22%3A%7B%22target%22%3A%22C3%27%22%2C%22id%22%3A%22side%22%2C%22remoteTrackingBranchID%22%3A%22o/master%22%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22side%22%2C%22id%22%3A%22HEAD%22%7D%2C%22originTree%22%3A%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C3%27%22%2C%22id%22%3A%22master%22%2C%22remoteTrackingBranchID%22%3Anull%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%7D%7D", - "solutionCommand": "git checkout -b side o/master;git commit;git pull --rebase;git push", + "solutionCommand": "git checkout -b side o/main;git commit;git pull --rebase;git push", "startTree": "{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\"},\"o/master\":{\"target\":\"C1\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", "name": { "en_US": "Remote Tracking", "zh_CN": "远程追踪", "zh_TW": "remote tracking", "es_AR": "Trackeando remotos", + "es_ES": "Trackeando remotos", "pt_BR": "Seguindo remotos", + "gl" : "Traceando os remotos", "de_DE": "Remote Tracking", "ja" : "リモートのトラッキング", "fr_FR": "Suivi de branche distante", "ru_RU": "Слежка за удалённым репозиторием", "ko" : "원격 저장소 추적하기", - "uk" : "Слідкуємо за віддаленим репозиторієм" + "uk" : "Слідкуємо за віддаленим репозиторієм", + "vi" : "Theo dõi từ xa", + "sl_SI": "Sledenje Oddaljenega Repota" }, "hint": { "en_US": "Remember there are two ways to set remote tracking!", "zh_CN": "记住,有两种设置 remote tracking 的方法!", "zh_TW": "記住喔,有兩個方式可以去設定 remote tracking", "es_AR": "¡Acordate de que hay dos formas de trackear un remoto!", + "es_ES": "¡Recuerda que hay dos formas de trackear un remoto!", "pt_BR": "Lembre-se que há duas formas de seguir um ramo remoto!", + "gl" : "¡Lembrate de que hai dúas formas de seguir unha rama remota!", "de_DE": "Nicht vergessen, es gibt zwei Arten Remote Tracking einzurichten!", "ja" : "リモートトラッキングを設定する方法が二つあるのをお忘れなく!", "fr_FR": "Rappelez-vous qu'il existe deux façons de configurer le suivi de branche distante !", "ru_RU": "Помни, есть два способа установить слежку за удалённым репозиторием!", "ko" : "원격 추적하기를 설정하는데에는 두가지 방법이 있습니다!", - "uk" : "Пам'ятай, є два способи слідкувати за віддаленим репозиорієм!" + "uk" : "Пам'ятай, є два способи слідкувати за віддаленим репозиорієм!", + "vi" : "Hãy nhớ rằng, có 2 cách để thiết lập theo dõi từ xa!", + "sl_SI": "Spomni se, da obstajata dva načina za sledenje oddaljenega repota." }, "startDialog": { "en_US": { @@ -37,10 +45,10 @@ exports.level = { "markdowns": [ "### Remote-Tracking branches", "", - "One thing that might have seemed \"magical\" about the last few lessons is that git knew the `master` branch was related to `o/master`. Sure these branches have similar names and it might make logical sense to connect the `master` branch on the remote to the local `master` branch, but this connection is demonstrated clearly in two scenarios:", + "One thing that might have seemed \"magical\" about the last few lessons is that git knew the `main` branch was related to `o/main`. Sure these branches have similar names and it might make logical sense to connect the `main` branch on the remote to the local `main` branch, but this connection is demonstrated clearly in two scenarios:", "", - "* During a pull operation, commits are downloaded onto `o/master` and then *merged* into the `master` branch. The implied target of the merge is determined from this connection.", - "* During a push operation, work from the `master` branch was pushed onto the remote's `master` branch (which was then represented by `o/master` locally). The *destination* of the push is determined from the connection between `master` and `o/master`.", + "* During a pull operation, commits are downloaded onto `o/main` and then *merged* into the `main` branch. The implied target of the merge is determined from this connection.", + "* During a push operation, work from the `main` branch was pushed onto the remote's `main` branch (which was then represented by `o/main` locally). The *destination* of the push is determined from the connection between `main` and `o/main`.", "" ] } @@ -51,17 +59,17 @@ exports.level = { "markdowns": [ "## Remote tracking", "", - "Long story short, this connection between `master` and `o/master` is explained simply by the \"remote tracking\" property of branches. The `master` branch is set to track `o/master` -- this means there is an implied merge target and implied push destination for the `master` branch.", + "Long story short, this connection between `main` and `o/main` is explained simply by the \"remote tracking\" property of branches. The `main` branch is set to track `o/main` -- this means there is an implied merge target and implied push destination for the `main` branch.", "", - "You may be wondering how this property got set on the `master` branch when you didn't run any commands to specify it. Well, when you clone a repository with git, this property is actually set for you automatically. ", + "You may be wondering how this property got set on the `main` branch when you didn't run any commands to specify it. Well, when you clone a repository with git, this property is actually set for you automatically. ", "", - "During a clone, git creates a remote branch for every branch on the remote (aka branches like `o/master`). It then creates a local branch that tracks the currently active branch on the remote, which is `master` in most cases.", + "During a clone, git creates a remote branch for every branch on the remote (aka branches like `o/main`). It then creates a local branch that tracks the currently active branch on the remote, which is `main` in most cases.", "", "Once git clone is complete, you only have one local branch (so you aren't overwhelmed) but you can see all the different branches on the remote (if you happen to be very curious). It's the best of both worlds!", "", "This also explains why you may see the following command output when cloning:", "", - " local branch \"master\" set to track remote branch \"o/master\"" + " local branch \"main\" set to track remote branch \"o/main\"" ] } }, @@ -71,13 +79,13 @@ exports.level = { "markdowns": [ "### Can I specify this myself?", "", - "Yes you can! You can make any arbitrary branch track `o/master`, and if you do so, that branch will have the same implied push destination and merge target as `master`. This means you can run `git push` on a branch named `totallyNotMaster` and have your work pushed to the `master` branch on the remote!", + "Yes you can! You can make any arbitrary branch track `o/main`, and if you do so, that branch will have the same implied push destination and merge target as `main`. This means you can run `git push` on a branch named `totallyNotMain` and have your work pushed to the `main` branch on the remote!", "", "There are two ways to set this property. The first is to checkout a new branch by using a remote branch as the specified ref. Running", "", - "`git checkout -b totallyNotMaster o/master`", + "`git checkout -b totallyNotMain o/main`", "", - "Creates a new branch named `totallyNotMaster` and sets it to track `o/master`." + "Creates a new branch named `totallyNotMain` and sets it to track `o/main`." ] } }, @@ -85,12 +93,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Enough talking, let's see a demonstration! We will checkout a new branch named `foo` and set it to track `master` on the remote." + "Enough talking, let's see a demonstration! We will checkout a new branch named `foo` and set it to track `main` on the remote." ], "afterMarkdowns": [ - "As you can see, we used the implied merge target of `o/master` to update the `foo` branch. Note how master doesn't get updated!!" + "As you can see, we used the implied merge target of `o/main` to update the `foo` branch. Note how main doesn't get updated!!" ], - "command": "git checkout -b foo o/master; git pull", + "command": "git checkout -b foo o/main; git pull", "beforeCommand": "git clone; git fakeTeamwork" } }, @@ -98,12 +106,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "This also applies for git push" + "This also applies for git push." ], "afterMarkdowns": [ - "Boom. We pushed our work to the `master` on the remote even though our branch was named something totally different" + "Boom. We pushed our work to the `main` on the remote even though our branch was named something totally different." ], - "command": "git checkout -b foo o/master; git commit; git push", + "command": "git checkout -b foo o/main; git commit; git push", "beforeCommand": "git clone" } }, @@ -115,11 +123,11 @@ exports.level = { "", "Another way to set remote tracking on a branch is to simply use the `git branch -u` option. Running", "", - "`git branch -u o/master foo`", + "`git branch -u o/main foo`", "", - "will set the `foo` branch to track `o/master`. If `foo` is currently checked out you can even leave it off:", + "will set the `foo` branch to track `o/main`. If `foo` is currently checked out you can even leave it off:", "", - "`git branch -u o/master`", + "`git branch -u o/main`", "" ] } @@ -133,7 +141,7 @@ exports.level = { "afterMarkdowns": [ "Same as before, just a more explicit command. Sweet!" ], - "command": "git branch -u o/master foo; git commit; git push", + "command": "git branch -u o/main foo; git commit; git push", "beforeCommand": "git clone; git checkout -b foo" } }, @@ -141,7 +149,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Ok! For this level let's push work onto the `master` branch on remote while *not* checked out on `master` locally. I'll let you figure out the rest since this is the advanced course :P" + "Ok! For this level let's push work onto the `main` branch on remote while *not* checked out on `main` locally. I'll let you figure out the rest since this is the advanced course :P" ] } } @@ -155,10 +163,10 @@ exports.level = { "markdowns": [ "### Le suivi des branches distantes", "", - "Dans les dernières leçons, git savait que la branche `master` était reliée à `o/master`, et cela a pu vous paraître \"magique\". Il est certain que ces deux branches ont des noms similaires et il peut être logique de croire que la branche locale `master` est liée à la branche distante `master`, mais la relation n'est prouvée que dans deux scénarios :", + "Dans les dernières leçons, git savait que la branche `main` était reliée à `o/main`, et cela a pu vous paraître \"magique\". Il est certain que ces deux branches ont des noms similaires et il peut être logique de croire que la branche locale `main` est liée à la branche distante `main`, mais la relation n'est prouvée que dans deux scénarios :", "", - "* Pendant un pull, les commits sont téléchargés dans `o/master` et ensuite *fusionnés* (merge) dans la branche `master`. La cible impliquée dans cette fusion est déterminée par cette relation.", - "* Pendant un push, le travail de la branche `master` a été envoyé sur la branche distante `master` (qui est localement représentée par `o/master`). La *destination* du push est déterminée par la relation entre `master` and `o/master`.", + "* Pendant un pull, les commits sont téléchargés dans `o/main` et ensuite *fusionnés* (merge) dans la branche `main`. La cible impliquée dans cette fusion est déterminée par cette relation.", + "* Pendant un push, le travail de la branche `main` a été envoyé sur la branche distante `main` (qui est localement représentée par `o/main`). La *destination* du push est déterminée par la relation entre `main` and `o/main`.", "" ] } @@ -169,17 +177,17 @@ exports.level = { "markdowns": [ "## Remote tracking", "", - "Pour faire court, cette relation entre `master` et `o/master` est simplement portée par la propriété \"remote tracking\" (suivi distant) des branches. La branche `master` est configurée pour suivre `o/master` : cela signifie qu'il y a une cible de fusion et une destination d'envoi implicites pour la branche `master`.", + "Pour faire court, cette relation entre `main` et `o/main` est simplement portée par la propriété \"remote tracking\" (suivi distant) des branches. La branche `main` est configurée pour suivre `o/main` : cela signifie qu'il y a une cible de fusion et une destination d'envoi implicites pour la branche `main`.", "", - "Vous vous demandez peut-être comment cette propriété a été configurée pour la branche `master` alors que vous n'avez exécuté aucune commande pour le faire. Eh bien, quand vous clonez un dépôt avec git, cette propriété est configurée automatiquement. ", + "Vous vous demandez peut-être comment cette propriété a été configurée pour la branche `main` alors que vous n'avez exécuté aucune commande pour le faire. Eh bien, quand vous clonez un dépôt avec git, cette propriété est configurée automatiquement. ", "", - "Pendant le clonage, git crée une branche distante pour chaque branche du dépôt distant (c'est à dire des branches comme `o/master`). Il crée ensuite une branche locale qui suit la branche actuellement active sur le dépôt distant, qui se trouve être `master` dans la plupart des cas.", + "Pendant le clonage, git crée une branche distante pour chaque branche du dépôt distant (c'est à dire des branches comme `o/main`). Il crée ensuite une branche locale qui suit la branche actuellement active sur le dépôt distant, qui se trouve être `main` dans la plupart des cas.", "", "Une fois que git clone est terminé, vous avez seulement une branche locale (comme ça vous n'êtes pas submergé) mais vous pouvez voir toutes les branches distantes (si vous êtes très curieux). C'est le compromis idéal !", "", "Cela explique aussi pourquoi vous avez peut-être vu la sortie suivante pendant le clonage :", "", - " local branch \"master\" set to track remote branch \"o/master\"" + " local branch \"main\" set to track remote branch \"o/main\"" ] } }, @@ -189,13 +197,13 @@ exports.level = { "markdowns": [ "### Puis-je configurer cette relation moi-même ?", "", - "Absolument ! Vous pouvez suivre `o/master` depuis n'importe quelle branche, et si vous le faîtes, cette branche va avoir la même destination de push et cible de merge que pour `master`. Cela signifie que vous pouvez exécuter `git push` sur une branche nommée `totallyNotMaster` mais envoyer tout de même votre travail sur la branche `master` du dépôt distant !", + "Absolument ! Vous pouvez suivre `o/main` depuis n'importe quelle branche, et si vous le faîtes, cette branche va avoir la même destination de push et cible de merge que pour `main`. Cela signifie que vous pouvez exécuter `git push` sur une branche nommée `totallyNotMain` mais envoyer tout de même votre travail sur la branche `main` du dépôt distant !", "", "Il y a deux façons de configurer cette propriété. La première est de créer une nouvelle branche en la branchant immédiatement sur la branche distante, à l'aide de `git checkout -b` :", "", - "`git checkout -b totallyNotMaster o/master`", + "`git checkout -b totallyNotMain o/main`", "", - "Cette commande crée une nouvelle branche nommée `totallyNotMaster` et la configure pour suivre `o/master`." + "Cette commande crée une nouvelle branche nommée `totallyNotMain` et la configure pour suivre `o/main`." ] } }, @@ -203,12 +211,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Assez parlé, faisons une démonstration ! Nous allons nous placer sur une nouvelle branche nommée `foo` et la configurer pour suivre `master` du dépôt distant." + "Assez parlé, faisons une démonstration ! Nous allons nous placer sur une nouvelle branche nommée `foo` et la configurer pour suivre `main` du dépôt distant." ], "afterMarkdowns": [ - "Comme vous pouvez le voir, nous avons utilisé la cible de fusion déclarée pour `o/master` afin de mettre à jour la branche `foo`. Remarquez que la branche master n'a pas été mise à jour !!" + "Comme vous pouvez le voir, nous avons utilisé la cible de fusion déclarée pour `o/main` afin de mettre à jour la branche `foo`. Remarquez que la branche main n'a pas été mise à jour !!" ], - "command": "git checkout -b foo o/master; git pull", + "command": "git checkout -b foo o/main; git pull", "beforeCommand": "git clone; git fakeTeamwork" } }, @@ -219,9 +227,9 @@ exports.level = { "Cela s'applique aussi pour git push :" ], "afterMarkdowns": [ - "Boum. Nous avons envoyé notre travail sur `master` vers le dépôt distant alors que notre branche avait un nom totalement différent." + "Boum. Nous avons envoyé notre travail sur `main` vers le dépôt distant alors que notre branche avait un nom totalement différent." ], - "command": "git checkout -b foo o/master; git commit; git push", + "command": "git checkout -b foo o/main; git commit; git push", "beforeCommand": "git clone" } }, @@ -233,11 +241,11 @@ exports.level = { "", "Une autre façon de configurer le suivi d'une branche est d'utiliser l'option `git branch -u`. La commande est alors :", "", - "`git branch -u o/master foo`", + "`git branch -u o/main foo`", "", - "Ce qui va configurer la branche `foo` (déjà existante) pour suivre `o/master`. Si `foo` est la branche courante, vous pouvez même ne pas la préciser :", + "Ce qui va configurer la branche `foo` (déjà existante) pour suivre `o/main`. Si `foo` est la branche courante, vous pouvez même ne pas la préciser :", "", - "`git branch -u o/master`", + "`git branch -u o/main`", "" ] } @@ -251,7 +259,7 @@ exports.level = { "afterMarkdowns": [ "C'est la même chose, et c'est juste un peu plus explicite. Cool !" ], - "command": "git branch -u o/master foo; git commit; git push", + "command": "git branch -u o/main foo; git commit; git push", "beforeCommand": "git clone; git checkout -b foo" } }, @@ -259,7 +267,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Ok ! Pour ce niveau, envoyons notre travail sur la branche distante `master` en ne se trouvant *pas* sur la branche `master` locale. Je vous laisse chercher comment faire, puisque c'est une leçon de niveau avancé :P" + "Ok ! Pour ce niveau, envoyons notre travail sur la branche distante `main` en ne se trouvant *pas* sur la branche `main` locale. Je vous laisse chercher comment faire, puisque c'est une leçon de niveau avancé :P" ] } } @@ -273,10 +281,10 @@ exports.level = { "markdowns": [ "### Ramas que trackean remotos", "", - "Una de las cosas que pueden haber parecido \"mágicas\" de las últimas lecciones es que git sabía que la rama `master` estaba relacionada con `o/master`. Obviamente, estas ramas tienen nombres parecidos, y podría parecer lógico conectar la rama `master` del remoto con la rama `master` local, pero esta conexión es bien evidente en dos escenarios:", + "Una de las cosas que pueden haber parecido \"mágicas\" de las últimas lecciones es que git sabía que la rama `main` estaba relacionada con `o/main`. Obviamente, estas ramas tienen nombres parecidos, y podría parecer lógico conectar la rama `main` del remoto con la rama `main` local, pero esta conexión es bien evidente en dos escenarios:", "", - "* Durante una operación de pull, los commits se descargan a `o/master` y después se *mergean* a la rama `master`. El objetivo implícito del merge se determina con esta conexión.", - "* Durante un push, el trabajo de la rama `master` se sube a la rama `master` del remoto (que estaba representada localmente por `o/master`). El *destino* del push se determina con esta conexión entre `master` y `o/master`.", + "* Durante una operación de pull, los commits se descargan a `o/main` y después se *mergean* a la rama `main`. El objetivo implícito del merge se determina con esta conexión.", + "* Durante un push, el trabajo de la rama `main` se sube a la rama `main` del remoto (que estaba representada localmente por `o/main`). El *destino* del push se determina con esta conexión entre `main` y `o/main`.", "" ] } @@ -287,19 +295,19 @@ exports.level = { "markdowns": [ "## Trackeando remotos", "", - "Haciéndola corta, esta conexión entre `master` y `o/master` se explica simplemente por la propiedad de \"trackear (seguir) remotos\" de las ramas. La rama `master` está configurada para trackear `o/master` -- osea, que hay un objetivo implícito para el merge y un destino implícito para de la rama `master`.", + "Haciéndola corta, esta conexión entre `main` y `o/main` se explica simplemente por la propiedad de \"trackear (seguir) remotos\" de las ramas. La rama `main` está configurada para trackear `o/main` -- osea, que hay un objetivo implícito para el merge y un destino implícito para de la rama `main`.", "", - "Podrías estar pensando cómo esa propiedad apareció en tu rama `master` si vos no corriste ningún comando para especificarlo. Bueno, cuando clonás un repositorio con git, esta propiedad se asigna por vos automáticamente.", + "Podrías estar pensando cómo esa propiedad apareció en tu rama `main` si vos no corriste ningún comando para especificarlo. Bueno, cuando clonás un repositorio con git, esta propiedad se asigna por vos automáticamente.", "", - "Durante un clone, git crea una rama remota por cada rama en el remoto (por ejemplo, ramas como `o/master`). Pero después crea una rama local que trackea la rama activa del remote, que suele ser `master`.", + "Durante un clone, git crea una rama remota por cada rama en el remoto (por ejemplo, ramas como `o/main`). Pero después crea una rama local que trackea la rama activa del remote, que suele ser `main`.", "", "Una vez completado el git clone, sólo tenés una única rama local (para que no te asustes) pero podés ver todas las ramas que del remoto (si fueras tan curioso). ¡Es lo mejor de ambos mundos!", "", "Esto también explica por qué podrías ver un mensaje como este durante la clonación:", "", - " local branch \"master\" set to track remote branch \"o/master\"", + " local branch \"main\" set to track remote branch \"o/main\"", "", - " rama local \"master\" establecida para trackear la rama remota \"o/master\"" + " rama local \"main\" establecida para trackear la rama remota \"o/main\"" ] } }, @@ -309,13 +317,13 @@ exports.level = { "markdowns": [ "### ¿Puedo especificarlo yo?", "", - "¡Claro que sí! Podés hacer que cualquier rama que quieras trackee `o/master`, y si lo hicieras, esa rama va a tener el mismo destino implícito de push y objetivo implícito de merge que `master`. Eso signfica que podés correr `git push` en una rama llamada `absolutamenteNoEsMaster` y ¡que tu trabajo se pushee a la rama `master` del remoto!", + "¡Claro que sí! Podés hacer que cualquier rama que quieras trackee `o/main`, y si lo hicieras, esa rama va a tener el mismo destino implícito de push y objetivo implícito de merge que `main`. Eso significa que podés correr `git push` en una rama llamada `absolutamenteNoEsMaster` y ¡que tu trabajo se pushee a la rama `main` del remoto!", "", "Hay dos formas de establecer esta propiedad. La primera es checkoutear una nueva rama usando una rama remota como la referencia especificada. Ejecutar", "", - "`git checkout -b absolutamenteNoEsMaster o/master`", + "`git checkout -b absolutamenteNoEsMaster o/main`", "", - "Crea una nueva rama llamada `absolutamenteNoEsMaster` y la hace trackear a `o/master`." + "Crea una nueva rama llamada `absolutamenteNoEsMaster` y la hace trackear a `o/main`." ] } }, @@ -323,12 +331,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Suficiente charla, ¡veamos una demo! Vamos a checkoutear una nueva rama llamada `foo` y hacer que trackee a `master` en el remoto." + "Suficiente charla, ¡veamos una demo! Vamos a checkoutear una nueva rama llamada `foo` y hacer que trackee a `main` en el remoto." ], "afterMarkdowns": [ - "Como podés ver, usamos el objetivo implícito de merge `o/master` para actualizar la rama `foo`. ¡Notá cómo `master` no fue actualizada!" + "Como podés ver, usamos el objetivo implícito de merge `o/main` para actualizar la rama `foo`. ¡Notá cómo `main` no fue actualizada!" ], - "command": "git checkout -b foo o/master; git pull", + "command": "git checkout -b foo o/main; git pull", "beforeCommand": "git clone; git fakeTeamwork" } }, @@ -336,12 +344,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Lo mismo aplica para git push" + "Lo mismo aplica para git push." ], "afterMarkdowns": [ - "Boom. Pusheamos nuestro trabajo a la rama `master` del remoto incluso cuando nuestra rama se llamaba totalmente distinto" + "Boom. Pusheamos nuestro trabajo a la rama `main` del remoto incluso cuando nuestra rama se llamaba totalmente distinto." ], - "command": "git checkout -b foo o/master; git commit; git push", + "command": "git checkout -b foo o/main; git commit; git push", "beforeCommand": "git clone" } }, @@ -353,11 +361,11 @@ exports.level = { "", "Otra forma de especificar la rama a trackear es usar la opción `git branch -u`. Ejecutando", "", - "`git branch -u o/master foo`", + "`git branch -u o/main foo`", "", - "establecemos que la rama `foo` trackee a `o/master`. Si encima estás parado en `foo`, incluso podés obviarlo:", + "establecemos que la rama `foo` trackee a `o/main`. Si encima estás parado en `foo`, incluso podés obviarlo:", "", - "`git branch -u o/master`", + "`git branch -u o/main`", "" ] } @@ -371,7 +379,7 @@ exports.level = { "afterMarkdowns": [ "Lo mismo que antes, sólo que con un comando bastante más explícito. ¡Una belleza!" ], - "command": "git branch -u o/master foo; git commit; git push", + "command": "git branch -u o/main foo; git commit; git push", "beforeCommand": "git clone; git checkout -b foo" } }, @@ -379,7 +387,127 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "¡Ok! Para este nivel, pusheá tu trabajo a la rama `master` del remoto *sin* estar parado sobre `master` localmente. Te dejo que te des cuenta del resto solo, que para algo este es el curso avanzado :P" + "¡Ok! Para este nivel, pusheá tu trabajo a la rama `main` del remoto *sin* estar parado sobre `main` localmente. Te dejo que te des cuenta del resto solo, que para algo este es el curso avanzado :P" + ] + } + } + ] + }, + "es_ES": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Ramas que trackean remotos", + "", + "Una de las cosas que te pueden haber parecido \"mágicas\" de las últimas lecciones es que git sabía que la rama `main` estaba relacionada con `o/main`. Obviamente, estas ramas tienen nombres parecidos, y podría parecer lógico conectar la rama `main` del remoto con la rama `main` local, pero esta conexión es bien evidente en dos escenarios:", + "", + "* Durante una operación de pull, los commits se descargan a `o/main` y después se *mergean* a la rama `main`. El objetivo implícito del merge se determina con esta conexión.", + "* Durante un push, el trabajo de la rama `main` se sube a la rama `main` del remoto (que estaba representada localmente por `o/main`). El *destino* del push se determina con esta conexión entre `main` y `o/main`.", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Trackeando remotos", + "", + "Resumiendo, esta conexión entre `main` y `o/main` se explica simplemente por la propiedad de \"trackear (seguir) remotos\" de las ramas. La rama `main` está configurada para trackear `o/main` -- osea, que hay un objetivo implícito para el merge y un destino implícito para de la rama `main`.", + "", + "Podrías estar pensando cómo esa propiedad apareció en tu rama `main` si no ejecutaste ningún comando para especificarlo. Bueno, cuando clonas un repositorio con git, esta propiedad es asignada por ti automáticamente.", + "", + "Durante un clone, git crea una rama remota por cada rama en el remoto (por ejemplo, ramas como `o/main`). Pero después crea una rama local que trackea la rama activa del remote, que suele ser `main`.", + "", + "Una vez completado el git clone, sólo tienes una única rama local (para que no te asustes) pero puedes ver todas las ramas del remoto (si fueses curioso). ¡Es lo mejor de ambos mundos!", + "", + "Esto también explica por qué podrías ver un mensaje como este durante la clonación:", + "", + " local branch \"main\" set to track remote branch \"o/main\"", + "", + " rama local \"main\" establecida para trackear la rama remota \"o/main\"" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### ¿Puedo especificarlo yo?", + "", + "¡Claro que sí! Puedes hacer que cualquier rama que quieras trackee `o/main`, y si lo hicieras, esa rama va a tener el mismo destino implícito de push y objetivo implícito de merge que `main`. Eso significa que puedes ejecutar `git push` en una rama llamada `absolutamenteNoEsMaster` y ¡que tu trabajo se pushee a la rama `main` del remoto!", + "", + "Hay dos formas de establecer esta propiedad. La primera es hacer checkout sobre una nueva rama usando una rama remota como la referencia especificada. Ejecutar", + "", + "`git checkout -b absolutamenteNoEsMaster o/main`", + "", + "Crea una nueva rama llamada `absolutamenteNoEsMaster` y la hace trackear a `o/main`." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Basta de charla, ¡veamos un ejemplo! Vamos a hacer checkout de una nueva rama llamada `foo` y hacer que trackee a `main` en el remoto." + ], + "afterMarkdowns": [ + "Como puedes ver, usamos el objetivo implícito de merge `o/main` para actualizar la rama `foo`. ¡Observa cómo `main` no fue actualizada!" + ], + "command": "git checkout -b foo o/main; git pull", + "beforeCommand": "git clone; git fakeTeamwork" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Lo mismo aplica para git push." + ], + "afterMarkdowns": [ + "Zas. Hacemos push de nuestro trabajo a la rama `main` del remoto incluso cuando nuestra rama se llamaba totalmente distinto." + ], + "command": "git checkout -b foo o/main; git commit; git push", + "beforeCommand": "git clone" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Forma número 2", + "", + "Otra forma de especificar la rama a trackear es usar la opción `git branch -u`. Ejecutando", + "", + "`git branch -u o/main foo`", + "", + "establecemos que la rama `foo` trackee a `o/main`. Si encima estás parado en `foo`, incluso puedes obviarlo:", + "", + "`git branch -u o/main`", + "" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Veamos rápidamente esta otra forma de especificar la rama a trackear..." + ], + "afterMarkdowns": [ + "Lo mismo que antes, sólo que con un comando bastante más explícito. ¡Muy útil!" + ], + "command": "git branch -u o/main foo; git commit; git push", + "beforeCommand": "git clone; git checkout -b foo" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "¡Perfecto! Para este nivel, haz push de tu trabajo a la rama `main` del remoto *sin* estar parado sobre `main` localmente. Te dejo que te des cuenta del resto solo, que para algo este es el curso avanzado :P" ] } } @@ -393,10 +521,10 @@ exports.level = { "markdowns": [ "### Seguindo ramos remotos", "", - "Uma coisa que pode ter parecido \"mágica\" nas lições passadas é que o Git sabia que o ramo `master` estava relacionado com o `o/master`. Certamente esses ramos possuem nomes similares, e tem todo sentido lógico conectar o ramo `master` do lado remoto com o ramo `master` local, mas essa conexão é demonstrada claramente em dois cenários:", + "Uma coisa que pode ter parecido \"mágica\" nas lições passadas é que o Git sabia que o ramo `main` estava relacionado com o `o/main`. Certamente esses ramos possuem nomes similares, e tem todo sentido lógico conectar o ramo `main` do lado remoto com o ramo `main` local, mas essa conexão é demonstrada claramente em dois cenários:", "", - "* Durante uma operação de pull, os commits são baixados em `o/master` e então são *mergidos* no ramo `master`. O alvo do merge é determinado a partir dessa conexão.", - "* Durante uma operação de push, o trabalho do ramo `master` local é enviado para o ramo `master` remoto (que é representado localmente por `o/master`). O *destino* do push é determinado da conexão entre `master` e `o/master`.", + "* Durante uma operação de pull, os commits são baixados em `o/main` e então são *mergidos* no ramo `main`. O alvo do merge é determinado a partir dessa conexão.", + "* Durante uma operação de push, o trabalho do ramo `main` local é enviado para o ramo `main` remoto (que é representado localmente por `o/main`). O *destino* do push é determinado da conexão entre `main` e `o/main`.", "" ] } @@ -407,17 +535,17 @@ exports.level = { "markdowns": [ "## Remote tracking", "", - "Resumindo a história, essa conexão entre `master` e `o/master` é explicada pela propriedade de \"remote tracking\" dos ramos. O ramo `master` é configurado para seguir o ramo `o/master` -- isso significa que existe um alvo implícito de merge e um destino implícito de push para o ramo `master`.", + "Resumindo a história, essa conexão entre `main` e `o/main` é explicada pela propriedade de \"remote tracking\" dos ramos. O ramo `main` é configurado para seguir o ramo `o/main` -- isso significa que existe um alvo implícito de merge e um destino implícito de push para o ramo `main`.", "", - "Você pode estar se perguntando como essa propriedade foi configurada no ramo `master` se você não executou nenhum comando ordenando que isso fosse feito. Bem, quando você clona um repositório com o Git, essa propriedade é configurada para você automaticamente. ", + "Você pode estar se perguntando como essa propriedade foi configurada no ramo `main` se você não executou nenhum comando ordenando que isso fosse feito. Bem, quando você clona um repositório com o Git, essa propriedade é configurada para você automaticamente. ", "", - "Durante a clonagem, o Git cria um ramo remoto para cada ramo que existe no repositório remoto (ou seja, ramos como o `o/master`). Ele cria então um ramo local que segue o ramo atualmente ativo no repositório remoto, que geralmente é o `master`.", + "Durante a clonagem, o Git cria um ramo remoto para cada ramo que existe no repositório remoto (ou seja, ramos como o `o/main`). Ele cria então um ramo local que segue o ramo atualmente ativo no repositório remoto, que geralmente é o `main`.", "", "Uma vez que a clonagem esteja completa, você terá apenas um único ramo local (para que você não seja sobrecarregado), mas você pode ver todos os ramos diferentes que existem no repositório remoto (caso você esteja curioso). É o melhor dos dois mundos!", "", "Isso também explica porque você vê a seguinte mensagem quando clona um repositório:", "", - " local branch \"master\" set to track remote branch \"o/master\"" + " local branch \"main\" set to track remote branch \"o/main\"" ] } }, @@ -427,13 +555,13 @@ exports.level = { "markdowns": [ "### Posso eu mesmo especificar isso?", "", - "Sim, você pode! Você pode fazer com que qualquer ramo arbitrário siga o `o/master`, e se você fizer isso, esse ramo terá o mesmo destino de push implícito que e o mesmo alvo de merge que o `master`. Isso significa que você pode executar `git push` em um ramo chamado `realmenteNaoSouOMaster` e ainda assim ter seu trabalho enviado ao ramo `master` do repositório remoto!", + "Sim, você pode! Você pode fazer com que qualquer ramo arbitrário siga o `o/main`, e se você fizer isso, esse ramo terá o mesmo destino de push implícito que e o mesmo alvo de merge que o `main`. Isso significa que você pode executar `git push` em um ramo chamado `realmenteNaoSouOMaster` e ainda assim ter seu trabalho enviado ao ramo `main` do repositório remoto!", "", "Há duas formas de configurar essa propriedade. A primeira consiste em fazer checkout de um novo ramo usando o ramo remoto como especificação de referência. Executar", "", - "`git checkout -b realmenteNaoSouOMaster o/master`", + "`git checkout -b realmenteNaoSouOMaster o/main`", "", - "Cria um novo ramo chamado `realmenteNaoSouOMaster` e o configura para seguir o `o/master`." + "Cria um novo ramo chamado `realmenteNaoSouOMaster` e o configura para seguir o `o/main`." ] } }, @@ -441,12 +569,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Já foi conversa o suficiente, vamos ver uma demonstração! Vamos fazer checkout de um novo ramo chamado `foo` e configurá-lo para seguir o `master` do repositório remoto." + "Já foi conversa o suficiente, vamos ver uma demonstração! Vamos fazer checkout de um novo ramo chamado `foo` e configurá-lo para seguir o `main` do repositório remoto." ], "afterMarkdowns": [ - "Como você pode ver, usamos o alvo implícito de merge do `o/master` para atualizar o ramo `foo`. Veja como o master local não sofreu atualização!!" + "Como você pode ver, usamos o alvo implícito de merge do `o/main` para atualizar o ramo `foo`. Veja como o main local não sofreu atualização!!" ], - "command": "git checkout -b foo o/master; git pull", + "command": "git checkout -b foo o/main; git pull", "beforeCommand": "git clone; git fakeTeamwork" } }, @@ -454,12 +582,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Isso também se aplica ao git push" + "Isso também se aplica ao git push." ], "afterMarkdowns": [ - "Boom. Nós enviamos nosso trabalho para o ramo remoto `master` ainda que nosso ramo local tivesse um nome completamente diferente" + "Boom. Nós enviamos nosso trabalho para o ramo remoto `main` ainda que nosso ramo local tivesse um nome completamente diferente." ], - "command": "git checkout -b foo o/master; git commit; git push", + "command": "git checkout -b foo o/main; git commit; git push", "beforeCommand": "git clone" } }, @@ -471,11 +599,11 @@ exports.level = { "", "Outra maneira de configurar remote tracking em um ramo é utilizando `git branch -u`. Executando", "", - "`git branch -u o/master foo`", + "`git branch -u o/main foo`", "", - "configuraremos o ramo local `foo` para seguir o `o/master`. Se `foo` for o que estiver atualmente em checkout, você pode inclusive omiti-lo:", + "configuraremos o ramo local `foo` para seguir o `o/main`. Se `foo` for o que estiver atualmente em checkout, você pode inclusive omiti-lo:", "", - "`git branch -u o/master`", + "`git branch -u o/main`", "" ] } @@ -489,7 +617,7 @@ exports.level = { "afterMarkdowns": [ "O mesmo de antes, apenas um comando mais explícito. Doce!" ], - "command": "git branch -u o/master foo; git commit; git push", + "command": "git branch -u o/main foo; git commit; git push", "beforeCommand": "git clone; git checkout -b foo" } }, @@ -497,7 +625,127 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Ok! Para este nível, vamos fazer push no ramo remoto `master` *sem estar* em um checkout do `master` local. Vou deixar você descobrir o resto, já que isto é um curso avançado :P" + "Ok! Para este nível, vamos fazer push no ramo remoto `main` *sem estar* em um checkout do `main` local. Vou deixar você descobrir o resto, já que isto é um curso avançado :P" + ] + } + } + ] + }, + "gl": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Ramas que trackean os remotos", + "", + "Unha das cousas que poden semellar \"máxicas\" das últimas leccións é que git sabía que a rama `main` estaba relacionada co `o/main`. Obviamente, estas ramas teñen nomes semellantes, e podería semellar lóxico conectar a rama `main` do remoto ca rama `main` local, pero esta conexión é ben evidente nos dous escenarios:", + "", + "* Durante unha operación de pull, os commits descarganse ó `o/main` e logo *mesturanse* á rama `main`. O obxectivo implícito do merge determinase con esta conexión.", + "* Durante un push, o traballo da rama `main` súbese á rama `main` do remoto (que estaba representada localmente por `o/main`). O *destino* do push determinouse con esta conexión entre `main` e `o/main`.", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Trackeando remotos", + "", + "Facéndoa curta, esta conexión entre `main` e `o/main` ensínase pola propiedade de \"trackear (seguir) remotos\" das ramas. A rama `main` está configurada para trackear `o/main` -- o que quere dicir, que hai un obxectivo implícito para o merge e un destino implícito para a rama `main`.", + "", + "Poderías estar pensando cómo esa propiedade apareceu na túa rama `main` se ti non executaches ningún comando para especificalo. Bueno, cando clonas un repositorio co git, esta propiedade asignase por ti automáticamente.", + "", + "Durante un clone, git crea unha rama remota por cada rama no remoto (por exemplo, ramas como `o/main`). Pero despois crea unha rama local que trakea a rama activa do remoto, que habitúa ser `main`.", + "", + "Una vez completado o git clone, só tés unha única rama local (para que non te asustes) pero podes ver todalas ramas que do remoto (se fora tan curioso). ¡É o mellor de ámbolos dous mundos!", + "", + "Esto tamén explica por qué poderías ver unha mensaxe como este durante a clonación:", + "", + " local branch \"main\" set to track remote branch \"o/main\"", + "", + " rama local \"main\" establecida para trackear a rama remota \"o/main\"" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### ¿Podo especificalo eu?", + "", + "¡Claro que sí! Podes facer que calquera rama que quixeras seguir `o/main`, e se o fixeras, esa rama vai ter o mesmo destino implícito de push e obxectivo implícito de merge que `main`. Eso significa que podes executar `git push` nunha rama chamada `nonMaster` e ¡que o teu traballo se empurre á rama `main` do remoto!", + "", + "Hai dúas formas de establecer esta propiedade. A primeira é facer checkout a unha nova rama empregando unha rama remota como a referencia especificada. Executar", + "", + "`git checkout -b nonMaster o/main`", + "", + "Crea unha nova rama chamada `nonMaster` e persigue a `o/main`." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Suficiente charla, ¡vexamos unha demo! Imos facer checkout a unha nova rama chamada `foo` e facer que siga a `main` no remoto." + ], + "afterMarkdowns": [ + "Como podes ver, empregamos o obxectivo implícito de merge `o/main` para actualizar a rama `foo`. ¡Nota como `main` non foi actualizada!" + ], + "command": "git checkout -b foo o/main; git pull", + "beforeCommand": "git clone; git fakeTeamwork" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "O mismo aplica para git push." + ], + "afterMarkdowns": [ + "Boom. Empurramos o noso traballo á rama `main` do remoto incluso cando a nosa rama se chamaba totalmete distinto." + ], + "command": "git checkout -b foo o/main; git commit; git push", + "beforeCommand": "git clone" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Forma número 2", + "", + "Outra forma de especificar a rama a seguir é usar a opción `git branch -u`. Executando", + "", + "`git branch -u o/main foo`", + "", + "establecemos que a rama `foo` segue a `o/mater`. Se por riba estás parado en `foo`, incluso podes obvialo:", + "", + "`git branch -u o/main`", + "" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Vexamos rápidamente está outra forma de especificar a rama a seguir..." + ], + "afterMarkdowns": [ + "O mesmo que antes, só que un comando bastante máis explícito. ¡Unha cousa preciosa!" + ], + "command": "git branch -u o/main foo; git commit; git push", + "beforeCommand": "git clone; git checkout -b foo" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "¡Ok! Para este nivel, empurra o teu traballo á rama `main` do remoto *sen* estar parado sobre `main` localmente. Déixote que te decates do resto ti só, que para algo estás nun nivel avanzado :P" ] } } @@ -511,10 +759,10 @@ exports.level = { "markdowns": [ "### remote tracking branch", "", - "在之前的課程中,有一件事情看起來很\"神奇\",那就是 git 知道 `master` branch 是對應到 `o/master` branch。當然這些 branch 有類似的名稱,所以可以大概猜到, local 的 `master` branch 可以對應到 remote 的 `master branch`,但是我們是在兩種情況下可以確定有這個對應關係:", + "在之前的課程中,有一件事情看起來很\"神奇\",那就是 git 知道 `main` branch 是對應到 `o/main` branch。當然這些 branch 有類似的名稱,所以可以大概猜到, local 的 `main` branch 可以對應到 remote 的 `main branch`,但是我們是在兩種情況下可以確定有這個對應關係:", "", - "* 在使用 `pull` 的時候,下載 commit 到 `o/master`,並且 `merge` 這些 commit 到 `master` branch,這就表示這個 merge 的目標是決定於這個對應關係。", - "* 在使用 `push` 的時候,在 `master` branch 上面的 commit 被 push 到 remote 上面的 `master` branch (它在 local 被表示成 `o/master`),這就表示 push 的目標是決定於 `master` 以及 `o/master` 之間的對應關係。", + "* 在使用 `pull` 的時候,下載 commit 到 `o/main`,並且 `merge` 這些 commit 到 `main` branch,這就表示這個 merge 的目標是決定於這個對應關係。", + "* 在使用 `push` 的時候,在 `main` branch 上面的 commit 被 push 到 remote 上面的 `main` branch (它在 local 被表示成 `o/main`),這就表示 push 的目標是決定於 `main` 以及 `o/main` 之間的對應關係。", "" ] } @@ -525,17 +773,17 @@ exports.level = { "markdowns": [ "## Remote tracking", "", - "長話短說,我們可以用 branch 上面的 \"remote tracking\" 特性來表示介於 `master` 以及 `o/master` 的對應關係,`master` branch 被設定用來追蹤(track) `o/master`,這就表示對於 `master` branch 來說的話,有一個 merge 的目標以及 push 的目標。", + "長話短說,我們可以用 branch 上面的 \"remote tracking\" 特性來表示介於 `main` 以及 `o/main` 的對應關係,`main` branch 被設定用來追蹤(track) `o/main`,這就表示對於 `main` branch 來說的話,有一個 merge 的目標以及 push 的目標。", "", - "你可能會覺得很奇怪,當你沒有下任何指令去設定的時候,關於 `master` branch 的對應關係是如何被設定的。喔!其實當你 clone 一個 repo 的時候,其實就已經自動幫你做設定了。 ", + "你可能會覺得很奇怪,當你沒有下任何指令去設定的時候,關於 `main` branch 的對應關係是如何被設定的。喔!其實當你 clone 一個 repo 的時候,其實就已經自動幫你做設定了。 ", "", - "在做 clone 的時候,git 會針對每一個在 remote 上面的 branch 建立一個 branch (例如 `o/master`),之後它會建立一個 local branch 來追蹤目前在 remote 上面的 active branch,在大部份的情況下,幾乎都是設定 `master` branch。", + "在做 clone 的時候,git 會針對每一個在 remote 上面的 branch 建立一個 branch (例如 `o/main`),之後它會建立一個 local branch 來追蹤目前在 remote 上面的 active branch,在大部份的情況下,幾乎都是設定 `main` branch。", "", "一旦 git 完成這個動作,你就只會有一個 local branch ,但是你可以看到所有在 remote 上面的不同的 branch,對於 local 和 remote 來說的話,這樣子是最好的!", "", "這也解釋了為什麼當你 clone 的時候可能會看到以下被輸出的指令:", "", - " local branch \"master\" set to track remote branch \"o/master\"" + " local branch \"main\" set to track remote branch \"o/main\"" ] } }, @@ -545,13 +793,13 @@ exports.level = { "markdowns": [ "### 我可以自己設定嗎?", "", - "是的你可以!你可以設定任何的 branch 來 track `o/master`, 假如你真的這麼做的話,那麼該 branch 的 push 及 merge 的目標就會跟 `master` 一樣。這就表示說你可以在 `totallyNotMaster` branch 上面執行 `git push`,並且 push 你的 commit 到 remote 的 `master` branch!", + "是的你可以!你可以設定任何的 branch 來 track `o/main`, 假如你真的這麼做的話,那麼該 branch 的 push 及 merge 的目標就會跟 `main` 一樣。這就表示說你可以在 `totallyNotMain` branch 上面執行 `git push`,並且 push 你的 commit 到 remote 的 `main` branch!", "", "有兩個方式可以設定,第一個就是藉由參考一個 remote branch 來 checkout 一個新的 branch。執行", "", - "`git checkout -b totallyNotMaster o/master`", + "`git checkout -b totallyNotMain o/main`", "", - "建立一個新的 `totallyNotMaster` branch 並且它會 track `o/master`。" + "建立一個新的 `totallyNotMain` branch 並且它會 track `o/main`。" ] } }, @@ -559,12 +807,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "說的好多,我們現在來看一個例子!我們會 checkout 一個新的 `foo` branch,而且該 branch 會被用來 track remote 上的 `master` branch。" + "說的好多,我們現在來看一個例子!我們會 checkout 一個新的 `foo` branch,而且該 branch 會被用來 track remote 上的 `main` branch。" ], "afterMarkdowns": [ - "就像你看到的,當 `o/master` 更新的時候,`foo` branch 也跟著一起被更新,要注意 master 並沒有被更新!" + "就像你看到的,當 `o/main` 更新的時候,`foo` branch 也跟著一起被更新,要注意 main 並沒有被更新!" ], - "command": "git checkout -b foo o/master; git pull", + "command": "git checkout -b foo o/main; git pull", "beforeCommand": "git clone; git fakeTeamwork" } }, @@ -575,9 +823,9 @@ exports.level = { "同樣適用於 `git push`" ], "afterMarkdowns": [ - "哇,即使我們的 branch 名稱完全一點關係都沒有,但我們還是 push 了 commit 到 remote 的 `master` branch 上面。" + "哇,即使我們的 branch 名稱完全一點關係都沒有,但我們還是 push 了 commit 到 remote 的 `main` branch 上面。" ], - "command": "git checkout -b foo o/master; git commit; git push", + "command": "git checkout -b foo o/main; git commit; git push", "beforeCommand": "git clone" } }, @@ -589,11 +837,11 @@ exports.level = { "", "另外一個設定 remote tracking 的方法是使用 `git branch -u` 這一個指令,執行", "", - "`git branch -u o/master foo`", + "`git branch -u o/main foo`", "", - "你就會看到 `foo` branch 被設定成 track `o/master`,如果你現在已經 checkout 到 foo 這個 branch 上面了,你就可以省略掉它:", + "你就會看到 `foo` branch 被設定成 track `o/main`,如果你現在已經 checkout 到 foo 這個 branch 上面了,你就可以省略掉它:", "", - "`git branch -u o/master`", + "`git branch -u o/main`", "" ] } @@ -607,7 +855,7 @@ exports.level = { "afterMarkdowns": [ "跟之前一樣,就只是一個更加明確的指令,讚啦!" ], - "command": "git branch -u o/master foo; git commit; git push", + "command": "git branch -u o/main foo; git commit; git push", "beforeCommand": "git clone; git checkout -b foo" } }, @@ -615,7 +863,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "好!在這個關卡中,我們要 push 我們的 commit 到 remote 上面的 `master` branch,但是我們*不* checkout 到 local 的 `master` branch。因為這是一個進階的課程,所以我會讓你明白其它的東西。:P" + "好!在這個關卡中,我們要 push 我們的 commit 到 remote 上面的 `main` branch,但是我們*不* checkout 到 local 的 `main` branch。因為這是一個進階的課程,所以我會讓你明白其它的東西。:P" ] } } @@ -629,10 +877,10 @@ exports.level = { "markdowns": [ "### 远程跟踪分支", "", - "在前几节课程中有件事儿挺神奇的,Git 好像知道 `master` 与 `o/master` 是相关的。当然这些分支的名字是相似的,可能会让你觉得是依此将远程分支 master 和本地的 master 分支进行了关联。这种关联在以下两种情况下可以清楚地得到展示:", + "在前几节课程中有件事儿挺神奇的,Git 好像知道 `main` 与 `o/main` 是相关的。当然这些分支的名字是相似的,可能会让你觉得是依此将远程分支 main 和本地的 main 分支进行了关联。这种关联在以下两种情况下可以清楚地得到展示:", "", - "* pull 操作时, 提交记录会被先下载到 o/master 上,之后再合并到本地的 master 分支。隐含的合并目标由这个关联确定的。", - "* push 操作时, 我们把工作从 `master` 推到远程仓库中的 `master` 分支(同时会更新远程分支 `o/master`) 。这个推送的目的地也是由这种关联确定的!", + "* pull 操作时, 提交记录会被先下载到 o/main 上,之后再合并到本地的 main 分支。隐含的合并目标由这个关联确定的。", + "* push 操作时, 我们把工作从 `main` 推到远程仓库中的 `main` 分支(同时会更新远程分支 `o/main`) 。这个推送的目的地也是由这种关联确定的!", "" ] } @@ -643,17 +891,17 @@ exports.level = { "markdowns": [ "## 远程跟踪", "", - "直接了当地讲,`master` 和 `o/master` 的关联关系就是由分支的“remote tracking”属性决定的。`master` 被设定为跟踪 `o/master` —— 这意味着为 `master` 分支指定了推送的目的地以及拉取后合并的目标。", + "直接了当地讲,`main` 和 `o/main` 的关联关系就是由分支的“remote tracking”属性决定的。`main` 被设定为跟踪 `o/main` —— 这意味着为 `main` 分支指定了推送的目的地以及拉取后合并的目标。", "", - "你可能想知道 `master` 分支上这个属性是怎么被设定的,你并没有用任何命令指定过这个属性呀!好吧, 当你克隆仓库的时候, Git 就自动帮你把这个属性设置好了。", + "你可能想知道 `main` 分支上这个属性是怎么被设定的,你并没有用任何命令指定过这个属性呀!好吧, 当你克隆仓库的时候, Git 就自动帮你把这个属性设置好了。", "", - "当你克隆时, Git 会为远程仓库中的每个分支在本地仓库中创建一个远程分支(比如 `o/master`)。然后再创建一个跟踪远程仓库中活动分支的本地分支,默认情况下这个本地分支会被命名为 `master`。", + "当你克隆时, Git 会为远程仓库中的每个分支在本地仓库中创建一个远程分支(比如 `o/main`)。然后再创建一个跟踪远程仓库中活动分支的本地分支,默认情况下这个本地分支会被命名为 `main`。", "", "克隆完成后,你会得到一个本地分支(如果没有这个本地分支的话,你的目录就是“空白”的),但是可以查看远程仓库中所有的分支(如果你好奇心很强的话)。这样做对于本地仓库和远程仓库来说,都是最佳选择。", "", "这也解释了为什么会在克隆的时候会看到下面的输出:", "", - " local branch \"master\" set to track remote branch \"o/master\"", + " local branch \"main\" set to track remote branch \"o/main\"", "" ] } @@ -664,13 +912,13 @@ exports.level = { "markdowns": [ "### 我能自己指定这个属性吗?", "", - "当然可以啦!你可以让任意分支跟踪 `o/master`, 然后该分支会像 `master` 分支一样得到隐含的 push 目的地以及 merge 的目标。 这意味着你可以在分支 `totallyNotMaster` 上执行 `git push`,将工作推送到远程仓库的 `master` 分支上。", + "当然可以啦!你可以让任意分支跟踪 `o/main`, 然后该分支会像 `main` 分支一样得到隐含的 push 目的地以及 merge 的目标。 这意味着你可以在分支 `totallyNotMain` 上执行 `git push`,将工作推送到远程仓库的 `main` 分支上。", "", "有两种方法设置这个属性,第一种就是通过远程分支检出一个新的分支,执行: ", "", - "`git checkout -b totallyNotMaster o/master`", + "`git checkout -b totallyNotMain o/main`", "", - "就可以创建一个名为 `totallyNotMaster` 的分支,它跟踪远程分支 `o/master`。" + "就可以创建一个名为 `totallyNotMain` 的分支,它跟踪远程分支 `o/main`。" ] } }, @@ -678,12 +926,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "闲话少说,咱们先看看演示!我们检出一个名叫 `foo` 的新分支,让其跟踪远程仓库中的 `master`" + "闲话少说,咱们先看看演示!我们检出一个名叫 `foo` 的新分支,让其跟踪远程仓库中的 `main`" ], "afterMarkdowns": [ - "正如你所看到的, 我们使用了隐含的目标 `o/master` 来更新 `foo` 分支。需要注意的是 master 并未被更新!" + "正如你所看到的, 我们使用了隐含的目标 `o/main` 来更新 `foo` 分支。需要注意的是 main 并未被更新!" ], - "command": "git checkout -b foo o/master; git pull", + "command": "git checkout -b foo o/main; git pull", "beforeCommand": "git clone; git fakeTeamwork" } }, @@ -694,9 +942,9 @@ exports.level = { "git push 同样适用" ], "afterMarkdowns": [ - "我们将一个并不叫 `master` 的分支上的工作推送到了远程仓库中的 `master` 分支上" + "我们将一个并不叫 `main` 的分支上的工作推送到了远程仓库中的 `main` 分支上" ], - "command": "git checkout -b foo o/master; git commit; git push", + "command": "git checkout -b foo o/main; git commit; git push", "beforeCommand": "git clone" } }, @@ -708,11 +956,11 @@ exports.level = { "", "另一种设置远程追踪分支的方法就是使用:`git branch -u` 命令,执行:", "", - "`git branch -u o/master foo`", + "`git branch -u o/main foo`", "", - "这样 `foo` 就会跟踪 `o/master` 了。如果当前就在 foo 分支上, 还可以省略 foo:", + "这样 `foo` 就会跟踪 `o/main` 了。如果当前就在 foo 分支上, 还可以省略 foo:", "", - "`git branch -u o/master`", + "`git branch -u o/main`", "" ] } @@ -726,7 +974,7 @@ exports.level = { "afterMarkdowns": [ "跟之前一样, 但这个命令更明确!" ], - "command": "git branch -u o/master foo; git commit; git push", + "command": "git branch -u o/main foo; git commit; git push", "beforeCommand": "git clone; git checkout -b foo" } }, @@ -734,7 +982,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "OK! 本节我们在**不**检出 `master` 分支的情况下将工作推送到的远程仓库中的 `master` 分支上。因为这是高级课程, 就不做过多的提示了! :P" + "OK! 本节我们在**不**检出 `main` 分支的情况下将工作推送到的远程仓库中的 `main` 分支上。因为这是高级课程, 就不做过多的提示了! :P" ] } } @@ -748,10 +996,10 @@ exports.level = { "markdowns": [ "### Remote Tracking Branches", "", - "In den letzten paar Leveln wirkte es womöglich etwas \"magisch\", dass Git automatisch wusste, dass der Branch `master` irgendwie mit `o/master` verwandt ist. Klar, sie haben ähnliche Namen und daher mag es logisch erscheinen sie in Verbindung zu bringen, aber offensichtlich wird es in zwei Szenarien:", + "In den letzten paar Leveln wirkte es womöglich etwas \"magisch\", dass Git automatisch wusste, dass der Branch `main` irgendwie mit `o/main` verwandt ist. Klar, sie haben ähnliche Namen und daher mag es logisch erscheinen sie in Verbindung zu bringen, aber offensichtlich wird es in zwei Szenarien:", "", - "* Beim `pull` werden Commits in `o/master` heruntergeladen und dann per *Merge* in den Branch `master` gebracht. Aus der Verbindung zwischen den beiden Branches leitet sich das Ziel des Merges ab.", - "* Beim `push` werden Commits vom `master` auf den `master` auf dem Remote Server geschoben (und die Änderung _danach_ in `o/master` abgebildet). Das *Ziel* des Push wird aus der Verbindung zwischen `master` und `o/master` abgeleitet.", + "* Beim `pull` werden Commits in `o/main` heruntergeladen und dann per *Merge* in den Branch `main` gebracht. Aus der Verbindung zwischen den beiden Branches leitet sich das Ziel des Merges ab.", + "* Beim `push` werden Commits vom `main` auf den `main` des Remote Servers geschoben (und die Änderung _danach_ im lokalen `o/main` Branch abgebildet). Das *Ziel* des Push wird aus der Verbindung zwischen `main` und `o/main` abgeleitet.", "" ] } @@ -760,13 +1008,13 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Langer Rede kurzer Sinn, die Verbindung zwischen `master` und `o/master` ist einfach die Eigenschaft des \"Remote Tracking\" dieser Branches. `master` ist so eingestellt, dass er `o/master` trackt -- das heißt es gibt ein implizites Ziel für `pull` und `push` Operationen auf dem `master` Branch.", + "Langer Rede kurzer Sinn, die Verbindung zwischen `main` und `o/main` ist einfach die Eigenschaft des \"Remote Tracking\" von Branches. `main` ist so eingestellt, dass er `o/main` trackt -- das heißt es gibt ein implizites Ziel für `pull` und `push` Operationen auf dem `main` Branch.", "", - "Du fragst dich vielleicht wieso diese Eigenschaft auf dem `master` definiert ist, wenn du das doch gar nicht explizit gemacht hast. Naja, beim Clonen eines Repository macht Git das für den `master` automatisch.", + "Du fragst dich vielleicht wieso diese Eigenschaft auf dem `main` definiert ist, wenn du das doch gar nicht explizit gemacht hast. Naja, beim Clonen eines Repository macht Git das für den `main` automatisch.", "", - "Während des Clonens erstellt Git einen Remote Branch für jeden Branch, den es auf dem Remote Server findet (also Branches wie `o/master`); dann erstellt es für den Branch, auf den auf dem entfernten Server `HEAD` zeigt (meistens `master`) automatisch einen lokalen Branch und stellt ihn so ein, dass er sein Gegenstück auf dem Server trackt. Deswegen hast du beim clonen vielleicht schon mal dies gesehen:", + "Während des Clonens erstellt Git einen Remote Branch für jeden Branch, den es auf dem Remote Server findet (also Branches wie `o/main`); dann erstellt es für den Branch, auf den auf dem entfernten Server `HEAD` zeigt (meistens `main`) automatisch einen lokalen Branch und stellt ihn so ein, dass er sein Gegenstück auf dem Server trackt. Deswegen hast du beim clonen vielleicht schon mal dies gesehen:", "", - " local branch \"master\" set to track remote branch \"o/master\"" + " local branch \"main\" set to track remote branch \"o/main\"" ] } }, @@ -776,13 +1024,13 @@ exports.level = { "markdowns": [ "### Kann ich das auch selbst machen?", "", - "Na klar! Du kannst jeden beliebigen Branch so einstellen, dass er `o/master` trackt, und wenn du das tust wird der Branch dieselben impliziten Zielangaben für `push` und `pull` haben wie `master`. Du kannst also `git push` auf dem Branch `absolut_nicht_master` ausführen und deine Commits auf `master` auf dem entfernten Server schieben lassen.", + "Na klar! Du kannst jeden beliebigen Branch so einstellen, dass er `o/main` trackt, und wenn du das tust wird der Branch dieselben impliziten Zielangaben für `push` und `pull` haben wie `main`. Du kannst also `git push` auf dem Branch `absolut_nicht_master` ausführen und deine Commits auf `main` des entfernten Servers schieben lassen.", "", "Es gibt zwei Möglichkeiten diese Eigenschaft zu definieren. Die erste ist, einen neuen lokalen Branch von einem Remote Branch auszuchecken. Wenn man", "", - " git checkout -b absolut_nicht_master o/master", + " git checkout -b absolut_nicht_master o/main", "", - "eingibt, wir ein neuer lokaler Branch namens `absolut_nicht_master` angelegt, der `o/master` trackt." + "eingibt, wird ein neuer lokaler Branch namens `absolut_nicht_master` angelegt, der `o/main` trackt." ] } }, @@ -790,12 +1038,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Genug gequatscht, schauen wir uns eine Demonstration an! Wir checken einen neuen Branch `foo` aus, so dass er `master` auf dem Server trackt." + "Genug gequatscht, schauen wir uns eine Demonstration an! Wir checken einen neuen Branch `foo` aus, so dass er `main` auf dem Server trackt." ], "afterMarkdowns": [ - "Wie du siehst benutzen wir der implizite Ziel beim `pull` um `foo` zu aktualisieren. Beachte, dass `master` nicht aktualisiert wird." + "Wie du siehst, benutzen wir das implizite Ziel beim `pull` um `foo` zu aktualisieren. Beachte, dass `main` nicht aktualisiert wird." ], - "command": "git checkout -b foo o/master; git pull", + "command": "git checkout -b foo o/main; git pull", "beforeCommand": "git clone; git fakeTeamwork" } }, @@ -806,9 +1054,9 @@ exports.level = { "Das gilt auch für `git push`." ], "afterMarkdowns": [ - "Bämm. Wir haben unsere Commits auf den `master` auf dem Server geschoben, obwohl unser lokaler Branch völlig anders heißt." + "Bämm. Wir haben unsere Commits auf den `main` auf dem Server geschoben, obwohl unser lokaler Branch völlig anders heißt." ], - "command": "git checkout -b foo o/master; git commit; git push", + "command": "git checkout -b foo o/main; git commit; git push", "beforeCommand": "git clone" } }, @@ -818,13 +1066,13 @@ exports.level = { "markdowns": [ "### Methode 2", "", - "Noch eine Möglichkeit um Remote Tracking auf einem Branch einzustellen, ist einfach `git branch -u` zu benutzen. Wenn man", + "Noch eine Möglichkeit um Remote Tracking auf einem Branch einzustellen, ist `git branch -u`. Wenn man", "", - " git branch -u o/master foo", + " git branch -u o/main foo", "", - "eingibt, wir damit der lokale Branch `foo` so eingestellt, dass er `o/master` trackt. Den Namen des lokalen Branch kannst du auch weglassen, falls du ihn eh aktuell ausgecheckt hast:", + "eingibt, wird damit der lokale Branch `foo` so eingestellt, dass er `o/main` trackt. Den Namen des lokalen Branch kannst du auch weglassen, falls du ihn eh aktuell ausgecheckt hast:", "", - " git branch -u o/master", + " git branch -u o/main", "" ] } @@ -836,9 +1084,9 @@ exports.level = { "Schauen wir uns auch diese Methode noch an ..." ], "afterMarkdowns": [ - "Genau wie vorher, nur ein bisschen ausführlicherer Befehl. Schick!" + "Genau wie vorher, nur ist der Befehl ein bisschen eindeutiger. Schick!" ], - "command": "git branch -u o/master foo; git commit; git push", + "command": "git branch -u o/main foo; git commit; git push", "beforeCommand": "git clone; git checkout -b foo" } }, @@ -846,7 +1094,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Ok. In diesem Level muss du Commits auf den `master` auf dem Server schieben, *ohne* den lokalen `master` ausgecheckt zu haben. Den Rest kannst du selbst herausfinden, schließlich ist das hier für Fortgeschrittene. :P" + "Ok. In diesem Level musst du Commits auf den `main` auf dem Server schieben, *ohne* den lokalen `main` ausgecheckt zu haben. Den Rest kannst du selbst herausfinden, schließlich ist das hier für Fortgeschrittene. :P" ] } } @@ -860,10 +1108,10 @@ exports.level = { "markdowns": [ "### Удалённые-отслеживаемые ветки", "", - "Единственное, что могло бы показаться вам \"магией\" в нескольких предыдущих уроках - это то, как git знает, что ветка `master` соответствует `o/master`. Конечно, эти ветки имеют схожие имена и связь между локальной и удалённой ветками `master` выглядит вполне логично, однако, эта связь наглядно продемонстрирована в двух сценариях:", + "Единственное, что могло бы показаться вам \"магией\" в нескольких предыдущих уроках - это то, как git знает, что ветка `main` соответствует `o/main`. Конечно, эти ветки имеют схожие имена и связь между локальной и удалённой ветками `main` выглядит вполне логично, однако, эта связь наглядно продемонстрирована в двух сценариях:", "", - "* Во время операции pull коммиты скачиваются в ветку `o/master` и затем *соединяются* в ветку `master`. Подразумеваемая цель слияния определяется исходя из этой связи.", - "* Во время операции push наработки из ветки `master` закачиваются на удалённую ветку `master` (которая в локальном представлении выглядит как `o/master`). *Пункт назначения* операции push определяется исходя из связи между `master` и `o/master`.", + "* Во время операции pull коммиты скачиваются в ветку `o/main` и затем *соединяются* в ветку `main`. Подразумеваемая цель слияния определяется исходя из этой связи.", + "* Во время операции push наработки из ветки `main` закачиваются на удалённую ветку `main` (которая в локальном представлении выглядит как `o/main`). *Пункт назначения* операции push определяется исходя из связи между `main` и `o/main`.", "" ] } @@ -874,19 +1122,19 @@ exports.level = { "markdowns": [ "## Удалённые-отслеживаемые ветки", "", - "Короче, связь между `master` и `o/master` объясняется не иначе как свойство \"удалённое отслеживание\" веток. Ветка `master` настроена так, чтобы следить за `o/master` -- это подразумевает наличие источника для merge и пункта назначения для push в контексте ветки `master`.", + "Короче, связь между `main` и `o/main` объясняется не иначе как свойство \"удалённое отслеживание\" веток. Ветка `main` настроена так, чтобы следить за `o/main` -- это подразумевает наличие источника для merge и пункта назначения для push в контексте ветки `main`.", "", - "Вы, должно быть, удивлены, как это отслеживание появилось на ветке `master`, если мы не запускали ни одной специфической команды. На самом деле, когда вы клонируете репозиторий, это слежение включается автоматически.", + "Вы, должно быть, удивлены, как это отслеживание появилось на ветке `main`, если мы не запускали ни одной специфической команды. На самом деле, когда вы клонируете репозиторий, это слежение включается автоматически.", "", - "В процессе клонирования git локально создаёт удалённые ветки для каждой ветки с удалённого репозитория (такие как `o/master`). Затем он - git - создаёт локальные ветки, которые отслеживают текущую, активную ветку на удалённом репозитории. В большинстве случаев - это `master`.", + "В процессе клонирования git локально создаёт удалённые ветки для каждой ветки с удалённого репозитория (такие как `o/main`). Затем он - git - создаёт локальные ветки, которые отслеживают текущую, активную ветку на удалённом репозитории. В большинстве случаев - это `main`.", "", "К тому моменту как `git clone` завершит своё выполнение, у вас будет лишь одна локальная ветка (так что вы ещё не сильно перегружены), но, если вам будет интересно, вы сможете увидеть все удалённые ветки (при желании).", "", "Именно это объясняет, почему сразу после клонирования вы видите в консоли надпись:", "", - " local branch \"master\" set to track remote branch \"o/master\"", + " local branch \"main\" set to track remote branch \"o/main\"", "", - " (локальная ветка \"master\" теперь следит за удалённой веткой \"o/master\") " + " (локальная ветка \"main\" теперь следит за удалённой веткой \"o/main\") " ] } }, @@ -896,13 +1144,13 @@ exports.level = { "markdowns": [ "### А могу ли я сделать это самостоятельно?", "", - "Само собой! Вы можете сказать любой из веток, чтобы она отслеживала `o/master`, и если вы так сделаете, эта ветка будет иметь такой же пункт назначения для push и merge как и локальная ветка `master`. Это значит, что вы можете выполнить `git push`, находясь на ветке `totallyNotMaster`, и все ваши наработки с ветки `totallyNotMaster` будут закачены на ветку `master` удалённого репозитория!", + "Само собой! Вы можете сказать любой из веток, чтобы она отслеживала `o/main`, и если вы так сделаете, эта ветка будет иметь такой же пункт назначения для push и merge как и локальная ветка `main`. Это значит, что вы можете выполнить `git push`, находясь на ветке `totallyNotMain`, и все ваши наработки с ветки `totallyNotMain` будут закачены на ветку `main` удалённого репозитория!", "", "Есть два способа сделать это. Первый - это выполнить checkout для новой ветки, указав удалённую ветку в качестве ссылки. Для этого необходимо выполнить команду", "", - "`git checkout -b totallyNotMaster o/master`", + "`git checkout -b totallyNotMain o/main`", "", - ", которая создаст новую ветку с именем `totallyNotMaster` и укажет ей следить за `o/master`." + ", которая создаст новую ветку с именем `totallyNotMain` и укажет ей следить за `o/main`." ] } }, @@ -910,12 +1158,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Хватит болтовни, давайте взглянем на демонстрацию! Мы выполним checkout для новой ветки `foo` и укажем ей, чтобы она отслеживала `master` с удалённого репозитория." + "Хватит болтовни, давайте взглянем на демонстрацию! Мы выполним checkout для новой ветки `foo` и укажем ей, чтобы она отслеживала `main` с удалённого репозитория." ], "afterMarkdowns": [ - "Как вы увидели, мы использовали `o/master`, чтобы обновить ветку `foo`. Обратите внимание, как обновился `master`!!" + "Как вы увидели, мы использовали `o/main`, чтобы обновить ветку `foo`. Обратите внимание, как обновился `main`!!" ], - "command": "git checkout -b foo o/master; git pull", + "command": "git checkout -b foo o/main; git pull", "beforeCommand": "git clone; git fakeTeamwork" } }, @@ -923,12 +1171,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Это работает также и для git push" + "Это работает также и для git push." ], "afterMarkdowns": [ - "Оп! Мы закачали наши наработки на ветку `master` нашего удалённого репозитория. При том, что наша локальная ветка называется абсолютно по-другому." + "Оп! Мы закачали наши наработки на ветку `main` нашего удалённого репозитория. При том, что наша локальная ветка называется абсолютно по-другому." ], - "command": "git checkout -b foo o/master; git commit; git push", + "command": "git checkout -b foo o/main; git commit; git push", "beforeCommand": "git clone" } }, @@ -940,11 +1188,11 @@ exports.level = { "", "Другой способ указать ветке отслеживать удалённую ветку — это просто использовать команду `git branch -u`. Выполнив команду", "", - "`git branch -u o/master foo`", + "`git branch -u o/main foo`", "", - "вы укажете ветке `foo` следить за `o/master`. А если вы ещё при этом находитесь на ветке `foo`, то её можно не указывать:", + "вы укажете ветке `foo` следить за `o/main`. А если вы ещё при этом находитесь на ветке `foo`, то её можно не указывать:", "", - "`git branch -u o/master`", + "`git branch -u o/main`", "" ] } @@ -958,7 +1206,7 @@ exports.level = { "afterMarkdowns": [ "Словом, всё как и раньше, просто отдельная, специальная команда. Здорово!" ], - "command": "git branch -u o/master foo; git commit; git push", + "command": "git branch -u o/main foo; git commit; git push", "beforeCommand": "git clone; git checkout -b foo" } }, @@ -966,7 +1214,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Отлично! Для выполнения этого уровня давайте выполним push наших наработок в ветку `master` на удалённом репозитории, при этом *не* скачивая и не создавая ветку `master` локально. Я объясню вам оставшееся чуть позже, т.к. это продвинутый курс :P" + "Отлично! Для выполнения этого уровня давайте выполним push наших наработок в ветку `main` на удалённом репозитории, при этом *не* скачивая и не создавая ветку `main` локально. Я объясню вам оставшееся чуть позже, т.к. это продвинутый курс :P" ] } } @@ -980,10 +1228,10 @@ exports.level = { "markdowns": [ "### リモートトラッキングブランチ", "", - "もしかしたら直近の幾つかの章で、あることが「魔法」に見えたかもしれません。それは、gitが`master`ブランチは`o/master`に関連していることを知っていたということです。確かにこれらのブランチは似た名前を持っていて、それは、リモートの`master`ブランチとローカルの`master`ブランチを繋ぐ論理的な意味を成すかもしれません。しかし、リモートトラッキングの関係が、次のような2つの手順を明確にしています:", + "もしかしたら直近の幾つかの章で、あることが「魔法」に見えたかもしれません。それは、gitが`main`ブランチは`o/main`に関連していることを知っていたということです。確かにこれらのブランチは似た名前を持っていて、それは、リモートの`main`ブランチとローカルの`main`ブランチを繋ぐ論理的な意味を成すかもしれません。しかし、リモートトラッキングの関係が、次のような2つの手順を明確にしています:", "", - "* プルの実行時は、コミットを`o/master`上にダウンロードし、`master`ブランチにそれを*マージ*します。マージの暗黙のターゲットは、リモートトラッキングの関係によって決められます。", - "* プッシュの実行時は、`master`ブランチの作業はリモートの`master`ブランチ(ローカルでは`o/master`によって表現されています)にプッシュされます。プッシュ動作の決定は、`master`と`o/master`のリモートトラッキングな関係から決定されます。", + "* プルの実行時は、コミットを`o/main`上にダウンロードし、`main`ブランチにそれを*マージ*します。マージの暗黙のターゲットは、リモートトラッキングの関係によって決められます。", + "* プッシュの実行時は、`main`ブランチの作業はリモートの`main`ブランチ(ローカルでは`o/main`によって表現されています)にプッシュされます。プッシュ動作の決定は、`main`と`o/main`のリモートトラッキングな関係から決定されます。", "" ] } @@ -994,17 +1242,17 @@ exports.level = { "markdowns": [ "## リモートトラッキング", "", - "かいつまんでは、`master`と`o/master`の関係は、単にそれぞれのブランチの\"remote traking\"というプロパティによって説召されます。`master`ブランチには`o/master`を追跡しているというように設定されているのです。これは、`master`ブランチのための暗黙のプッシュ先と暗黙の取り込み先が存在することを意味します。", + "かいつまんでは、`main`と`o/main`の関係は、単にそれぞれのブランチの\"remote traking\"というプロパティによって説召されます。`main`ブランチには`o/main`を追跡しているというように設定されているのです。これは、`main`ブランチのための暗黙のプッシュ先と暗黙の取り込み先が存在することを意味します。", "", - "あなたは特に何も指定せずにコマンドを走らせていたのに、`master`ブランチにこのプロパティが設定されていたことに疑問を持つかもしれません。そう、gitによってリポジトリを複製した時、gitは実はこのプロパティを自動的に設定してくれるのです。", + "あなたは特に何も指定せずにコマンドを走らせていたのに、`main`ブランチにこのプロパティが設定されていたことに疑問を持つかもしれません。そう、gitによってリポジトリを複製した時、gitは実はこのプロパティを自動的に設定してくれるのです。", "", - "クローンしている間、gitはリモートブランチをリモートのブランチ全てに対して作ります(例えば、`o/master`のような感じです)。その後、現在アクティブなブランチを追跡するローカルブランチを作成します。多くの場合それは`master`ブランチになります。", + "クローンしている間、gitはリモートブランチをリモートのブランチ全てに対して作ります(例えば、`o/main`のような感じです)。その後、現在アクティブなブランチを追跡するローカルブランチを作成します。多くの場合それは`main`ブランチになります。", "", "gitのクローンが完了した時、あなたの手にはたった一つだけローカルブランチがあります(なので、閉口しないでも大丈夫です)。しかし、あなたは全てのリモートのブランチ同士の違いを見ることができるのです(もし、あなたがそれについて非常に好奇心旺盛であるときはいつでもね!)。これは、両方の世界にとってベストです!", "", "これはクローン中に次のようなコマンド出力が表示されることも説明します:", "", - " local branch \"master\" set to track remote branch \"o/master\"" + " local branch \"main\" set to track remote branch \"o/main\"" ] } }, @@ -1014,13 +1262,13 @@ exports.level = { "markdowns": [ "### 私は自分でトラッキングを設定できますか?", "", - "はい、できます!あなたは、全てのブランチについて`o/master`との追跡を設定でき、もしそうした時は、同じ暗黙のプッシュ先と取り込み先を`master`として設定します。これは、例えば`tottallyNotMaster`という名前のブランチで`git push`を走らせ、作業をリモートの`master`ブランチにプッシュするといったことができるということを意味しています!", + "はい、できます!あなたは、全てのブランチについて`o/main`との追跡を設定でき、もしそうした時は、同じ暗黙のプッシュ先と取り込み先を`main`として設定します。これは、例えば`tottallyNotMaster`という名前のブランチで`git push`を走らせ、作業をリモートの`main`ブランチにプッシュするといったことができるということを意味しています!", "", "このプロパティを設定するには2つの方法があります。一つ目は、リモートブランチのリファレンスを使用して新しいブランチをチェックアウトするというものです。例えば次のコマンドを走らせてます", "", - "`git checkout -b totallyNotMaster o/master`", + "`git checkout -b totallyNotMain o/main`", "", - "これは`totallyNotMaster`という名前のブランチを新しく作り、`o/master`への追跡プロパティを設定します。" + "これは`totallyNotMain`という名前のブランチを新しく作り、`o/main`への追跡プロパティを設定します。" ] } }, @@ -1028,12 +1276,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "説明は十分でしょう、デモを見ていきましょう!`foo`という名前の新しいブランチをチェックアウトし、リモートの`master`への追跡プロパティを設定してみます。" + "説明は十分でしょう、デモを見ていきましょう!`foo`という名前の新しいブランチをチェックアウトし、リモートの`main`への追跡プロパティを設定してみます。" ], "afterMarkdowns": [ - "私たちは暗黙の取り込み先である`o/master`を使って、`foo`ブランチを更新します。`master`は更新されないことに注意してください!!" + "私たちは暗黙の取り込み先である`o/main`を使って、`foo`ブランチを更新します。`main`は更新されないことに注意してください!!" ], - "command": "git checkout -b foo o/master; git pull", + "command": "git checkout -b foo o/main; git pull", "beforeCommand": "git clone; git fakeTeamwork" } }, @@ -1044,9 +1292,9 @@ exports.level = { "これは`git push`にも適用されます" ], "afterMarkdowns": [ - "わーお。全く違う名前がつけられているブランチですが、リモートの`master`に私たちの作業をプッシュできました。" + "わーお。全く違う名前がつけられているブランチですが、リモートの`main`に私たちの作業をプッシュできました。" ], - "command": "git checkout -b foo o/master; git commit; git push", + "command": "git checkout -b foo o/main; git commit; git push", "beforeCommand": "git clone" } }, @@ -1058,11 +1306,11 @@ exports.level = { "", "ブランチのリモートトラッキングを設定するもう一つの方法は、単に`git branch -u`オプションを使うというものです。例えば以下のようにです", "", - "`git branch -u o/master foo`", + "`git branch -u o/main foo`", "", - "これは、`foo`ブランチを`o/master`を追跡するように設定します。もし、`foo`が現在チェックアウトしているブランチだった場合、以下のように省略することができます:", + "これは、`foo`ブランチを`o/main`を追跡するように設定します。もし、`foo`が現在チェックアウトしているブランチだった場合、以下のように省略することができます:", "", - "`git branch -u o/master`", + "`git branch -u o/main`", "" ] } @@ -1076,7 +1324,7 @@ exports.level = { "afterMarkdowns": [ "前回と一緒で、より明示的なコマンドですね。とてもいい感じです!" ], - "command": "git branch -u o/master foo; git commit; git push", + "command": "git branch -u o/main foo; git commit; git push", "beforeCommand": "git clone; git checkout -b foo" } }, @@ -1084,7 +1332,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "OK!このレベルでは、ローカルで`master`にチェックアウトしていない状態で、リモートの`master`ブランチに作業をプッシュしてみましょう。これは高度な課題ですから、理解するのに少し時間をおく必要があると言っておきます:P" + "OK!このレベルでは、ローカルで`main`にチェックアウトしていない状態で、リモートの`main`ブランチに作業をプッシュしてみましょう。これは高度な課題ですから、理解するのに少し時間をおく必要があると言っておきます:P" ] } } @@ -1098,10 +1346,10 @@ exports.level = { "markdowns": [ "### 원격-추적 브랜치", "", - "지난 몇개의 레슨에서 \"마법\"처럼 보일 수 있는게 하나 있었는데, git이 `master`브랜치가 `o/master`와 연관 되어있는걸 안다는 것입니다. 물론 이 두 브랜치가 이름이 비슷하기 때문에 로컬 `master`브랜치가 원격의 `master`브랜치와 연결 되어있다고 하자면 어찌 논리적으로 말이 되긴 합니다만..., 이 연결은 두가지 시나리오를 통해 뚜렷하게 확인이 됩니다:", + "지난 몇개의 레슨에서 \"마법\"처럼 보일 수 있는게 하나 있었는데, git이 `main`브랜치가 `o/main`와 연관 되어있는걸 안다는 것입니다. 물론 이 두 브랜치가 이름이 비슷하기 때문에 로컬 `main`브랜치가 원격의 `main`브랜치와 연결 되어있다고 하자면 어찌 논리적으로 말이 되긴 합니다만..., 이 연결은 두가지 시나리오를 통해 뚜렷하게 확인이 됩니다:", "", - "* pull 작업을 하는 도중, 커밋들은 `o/master`에 내려받아 지고 그다음 `master` 브랜치로 *merge*됩니다. merge에서 내재된 타겟은 이 연결에서 결정합니다.", - "* push 작업을 하는 도중, `master` 브랜치의 작업은 원격의 `master`브랜치(로컬에서 `o/master`로 표현되는)로 push 됩니다. push의 *목적지*는 master와 `o/master`의 연결에서 결정됩니다.", + "* pull 작업을 하는 도중, 커밋들은 `o/main`에 내려받아 지고 그다음 `main` 브랜치로 *merge*됩니다. merge에서 내재된 타겟은 이 연결에서 결정합니다.", + "* push 작업을 하는 도중, `main` 브랜치의 작업은 원격의 `main`브랜치(로컬에서 `o/main`로 표현되는)로 push 됩니다. push의 *목적지*는 master와 `o/main`의 연결에서 결정됩니다.", "" ] } @@ -1112,17 +1360,17 @@ exports.level = { "markdowns": [ "## 원격 추적", "", - "간단히 말해서, 이 `master`와 `o/master`사이의 연결은 브랜치의 \"원격 추적\" 속성을 통해 간단하게 설명됩니다. `master`브랜치는 `o/master`브랜치를 추적하도록 설정되어 있습니다 -- 이것은 `master`가 merge와 push할 내재된 목적지가 생겼다는 뜻 입니다.", + "간단히 말해서, 이 `main`와 `o/main`사이의 연결은 브랜치의 \"원격 추적\" 속성을 통해 간단하게 설명됩니다. `main`브랜치는 `o/main`브랜치를 추적하도록 설정되어 있습니다 -- 이것은 `main`가 merge와 push할 내재된 목적지가 생겼다는 뜻 입니다.", "", - "여러분은 어떻게 이 속성을 지정해주는 그 어떤 명령어 없이 `master` 브랜치에 설정되있는지 궁금할것 입니다. 사실, 여러분이 git으로 저장소를 clone할때 이 속성이 여러분을 위해 자동으로 설정 됩니다.", + "여러분은 어떻게 이 속성을 지정해주는 그 어떤 명령어 없이 `main` 브랜치에 설정되있는지 궁금할것 입니다. 사실, 여러분이 git으로 저장소를 clone할때 이 속성이 여러분을 위해 자동으로 설정 됩니다.", "", - "clone을 진행하면서 git은 원격 저장소에있는 모든 브랜치에 대해 로컬에 원격 브랜치를 생성합니다(`o/master`같은것들 말이죠). 그 후 원격 저장소에서 현재 active한 브랜치를 추적하는 로컬 브랜치를 생성합니다, 대부분의 경우 `master`가 됩니다.", + "clone을 진행하면서 git은 원격 저장소에있는 모든 브랜치에 대해 로컬에 원격 브랜치를 생성합니다(`o/main`같은것들 말이죠). 그 후 원격 저장소에서 현재 active한 브랜치를 추적하는 로컬 브랜치를 생성합니다, 대부분의 경우 `main`가 됩니다.", "", "git clone이 완료되면, 여러분은 오로지 하나의 로컬 브랜치를 가지게 됩니다(부담스럽지 않도록) 물론 원격 저장소에있는 여러 다른 브랜치도 여전히 확인할 수 있습니다(호기심이 많으시다면). 로컬, 원격 저장소 양쪽에 최적화 되있는거죠!", "", "여러분이 clone을 할 때 아래의 명령어를 볼 수도 있는 이유입니다:", "", - " local branch \"master\" set to track remote branch \"o/master\"" + " local branch \"main\" set to track remote branch \"o/main\"" ] } }, @@ -1132,13 +1380,13 @@ exports.level = { "markdowns": [ "### 내 스스로 지정할수도 있나요?", "", - "당연하죠! 여러분은 아무 임의의 브랜치를 `o/master`를 추적하게 만들 수 있습니다. 이렇게 하면 이 브랜치 또한 내재된 push,merge 목적지를 `master`로 할 것입니다. 여러분은 이제 `totallyNotMaster`라는 브랜치에서 `git push`를 수행해서 원격 저장소의 브랜치 `master`로 작업을 push할 수 있습니다!", + "당연하죠! 여러분은 아무 임의의 브랜치를 `o/main`를 추적하게 만들 수 있습니다. 이렇게 하면 이 브랜치 또한 내재된 push,merge 목적지를 `main`로 할 것입니다. 여러분은 이제 `totallyNotMain`라는 브랜치에서 `git push`를 수행해서 원격 저장소의 브랜치 `main`로 작업을 push할 수 있습니다!", "", "이 속성을 설정하는데에는 두가지 방법이 있습니다. 첫 번째는 지정한 원격 브랜치를 참조해서 새로운 브랜치를 생성하여 checkout 하는 방법 입니다. 다음을 실행하면", "", - "`git checkout -b totallyNotMaster o/master`", + "`git checkout -b totallyNotMain o/main`", "", - "`totallyNotMaster`라는 이름의 새 브랜치를 생성하고 `o/master`를 추적하게 설정합니다." + "`totallyNotMain`라는 이름의 새 브랜치를 생성하고 `o/main`를 추적하게 설정합니다." ] } }, @@ -1146,12 +1394,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "설명은 충분히 한듯 합니다. 직접 확인해 봅시다! `foo`라는 이름의 새 브랜치를 checkout하고 이것을 원격 저장소의 `master`를 추적하도록 설정하겠습니다." + "설명은 충분히 한듯 합니다. 직접 확인해 봅시다! `foo`라는 이름의 새 브랜치를 checkout하고 이것을 원격 저장소의 `main`를 추적하도록 설정하겠습니다." ], "afterMarkdowns": [ - "보이듯이, 우리는 `o/master`를 `foo` 브랜치를 갱신하기 위한 내재된 merge 타겟으로 사용하고 있습니다. master가 갱신되지 않는다는것을 눈치챘죠?" + "보이듯이, 우리는 `o/main`를 `foo` 브랜치를 갱신하기 위한 내재된 merge 타겟으로 사용하고 있습니다. main이 갱신되지 않는다는것을 눈치챘죠?" ], - "command": "git checkout -b foo o/master; git pull", + "command": "git checkout -b foo o/main; git pull", "beforeCommand": "git clone; git fakeTeamwork" } }, @@ -1162,9 +1410,9 @@ exports.level = { "git push에도 적용이 됩니다" ], "afterMarkdowns": [ - "Boom. 브랜치의 이름을 전혀 다른것으로 지었는데도 불구하고 우리 작업이 `master`로 push 되었습니다." + "Boom. 브랜치의 이름을 전혀 다른것으로 지었는데도 불구하고 우리 작업이 `main`로 push 되었습니다." ], - "command": "git checkout -b foo o/master; git commit; git push", + "command": "git checkout -b foo o/main; git commit; git push", "beforeCommand": "git clone" } }, @@ -1176,11 +1424,11 @@ exports.level = { "", "브랜치에 원격 추적 설정을 하는 또 다른 방법으로는 간단하게 `git branch -u` 옵션을 사용하는 방법이 있습니다. 다음을 실행하면", "", - "`git branch -u o/master foo`", + "`git branch -u o/main foo`", "", - "가 `foo` 브랜치가 `o/master`를 추적하도록 설정합니다. 만약 `foo`가 현재 작업하고 있는 브랜치라면 생략해도 됩니다:", + "가 `foo` 브랜치가 `o/main`를 추적하도록 설정합니다. 만약 `foo`가 현재 작업하고 있는 브랜치라면 생략해도 됩니다:", "", - "`git branch -u o/master`", + "`git branch -u o/main`", "" ] } @@ -1194,7 +1442,7 @@ exports.level = { "afterMarkdowns": [ "이전과 같습니다, 좀 더 분명하게 알 수 있느 명령어죠. 좋아요!" ], - "command": "git branch -u o/master foo; git commit; git push", + "command": "git branch -u o/main foo; git commit; git push", "beforeCommand": "git clone; git checkout -b foo" } }, @@ -1202,7 +1450,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - " 이번 레벨에서는 로컬의 `master`브랜치가 아닌 다른 브랜치에서 작업을 원격 저장소의 `master`브랜치로 push하세요. 고급 과정이니 더 길게 설명하지는 않을게요 :p" + " 이번 레벨에서는 로컬의 `main`브랜치가 아닌 다른 브랜치에서 작업을 원격 저장소의 `main`브랜치로 push하세요. 고급 과정이니 더 길게 설명하지는 않을게요 :p" ] } } @@ -1216,10 +1464,10 @@ exports.level = { "markdowns": [ "### Гілки віддаленого стеження", "", - "Одна з речей в попередніх уроках, яка могла виглядати, наче \"магія\" -- це те, що гіт якось знає, що локальна гілка `master` відповідає віддаленій `o/master`. Звичайно, ці гілки мають схожі назви, і виглядає логічним співставити віддалену гілку `master` з локальною `master`, однак цей зв'язок найкраще видно в двох випадках:", + "Одна з речей в попередніх уроках, яка могла виглядати, наче \"магія\" -- це те, що гіт якось знає, що локальна гілка `main` відповідає віддаленій `o/main`. Звичайно, ці гілки мають схожі назви, і виглядає логічним співставити віддалену гілку `main` з локальною `main`, однак цей зв'язок найкраще видно в двох випадках:", "", - "* Під час операції `pull`, коміти попадають в `o/master`, а вже потім *мерджаться* в локальний `master`. Гілка в яку відбудеться мердж якраз і визначається цим зв'язком.", - "* Під час операції `push`, коміти з гілки `master` переносяться у віддалений `master` (який локально представлений як `o/master`). *Гілка-призначення* для `push` визначена зв'язком між `master` і `o/master`.", + "* Під час операції `pull`, коміти попадають в `o/main`, а вже потім *мерджаться* в локальний `main`. Гілка в яку відбудеться мердж якраз і визначається цим зв'язком.", + "* Під час операції `push`, коміти з гілки `main` переносяться у віддалений `main` (який локально представлений як `o/main`). *Гілка-призначення* для `push` визначена зв'язком між `main` і `o/main`.", "" ] } @@ -1230,17 +1478,17 @@ exports.level = { "markdowns": [ "## Гілки віддаленого стеження", "", - "В двох словах, цей зв'язок між `master` та `o/master` і є тим \"віддаленим стеженням\", визначеним для гілки. Гілка `master` налаштована стежити за `o/master` -- це визначає неявну ціль для мерджу і неявне призначення під час операції `push` для гілки `master`.", + "В двох словах, цей зв'язок між `main` та `o/main` і є тим \"віддаленим стеженням\", визначеним для гілки. Гілка `main` налаштована стежити за `o/main` -- це визначає неявну ціль для мерджу і неявне призначення під час операції `push` для гілки `main`.", "", "Ви можете подумати, а як же такий зв'язок було встановлено, якщо я не виконував жодної команди? Ну, коли гіт клонує репозиторій, він встановлює цей зв'язок автоматично.", "", - "Під час клонування гіт створює гілки для стеження за кожною гілкою віддаленого репозиторію (напр. `o/master`). Потім він створює локальну гілку, що пов'язана і стежить за активною гілкою у віддаленому репозиторії, яка в більшості випадків називається `master`.", + "Під час клонування гіт створює гілки для стеження за кожною гілкою віддаленого репозиторію (напр. `o/main`). Потім він створює локальну гілку, що пов'язана і стежить за активною гілкою у віддаленому репозиторії, яка в більшості випадків називається `main`.", "", "Після закінчення клонування у вас буде лише одна локальна гілка (щоб не перевантажувати) але ви можете переглянути всі віддалені гілки (якщо буде цікаво). Такий собі розумний компроміс!", "", "Це пояснює чому ви бачите наступне повідомлення під час клонування:", "", - " local branch \"master\" set to track remote branch \"o/master\"" + " local branch \"main\" set to track remote branch \"o/main\"" ] } }, @@ -1250,13 +1498,13 @@ exports.level = { "markdowns": [ "### А можу я сам вибирати?", "", - "Так, можеш! Ти можеш вибрати довільну гілку, яка слідкуватиме за `o/master`, і тоді для цієї гілки `push` та `merge` автоматично працюватимуть з `master`. Це означає, що виконання `git push` в гілці з назвою `totallyNotMaster` (зовсім не master) може зберегти локальні коміти у віддалену гілку `master`!", + "Так, можеш! Ти можеш вибрати довільну гілку, яка слідкуватиме за `o/main`, і тоді для цієї гілки `push` та `merge` автоматично працюватимуть з `main`. Це означає, що виконання `git push` в гілці з назвою `totallyNotMain` (зовсім не main) може зберегти локальні коміти у віддалену гілку `main`!", "", "Є два шляхи встановити такий зв'язок. Перший - створити нову гілку з явним вказанням зв'язку (за ким слідкувати). Виконання", "", - "`git checkout -b totallyNotMaster o/master`", + "`git checkout -b totallyNotMain o/main`", "", - "створить гілку `totallyNotMaster`, яка слідкує за `o/master`." + "створить гілку `totallyNotMain`, яка слідкує за `o/main`." ] } }, @@ -1264,12 +1512,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Досить розмов, подивімось в дії! Створімо нову гілку `foo` і змусьмо її слідкувати за віддаленою гілкою `master`." + "Досить розмов, подивімось в дії! Створімо нову гілку `foo` і змусьмо її слідкувати за віддаленою гілкою `main`." ], "afterMarkdowns": [ - "Як видно з результату, при оновленні `foo` було використано автоматичний зв'язок з `o/master` під час операції `merge`. Зверніть увагу, `master` не було оновлено!" + "Як видно з результату, при оновленні `foo` було використано автоматичний зв'язок з `o/main` під час операції `merge`. Зверніть увагу, `main` не було оновлено!" ], - "command": "git checkout -b foo o/master; git pull", + "command": "git checkout -b foo o/main; git pull", "beforeCommand": "git clone; git fakeTeamwork" } }, @@ -1277,12 +1525,12 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Це також справджується і для git push" + "Це також справджується і для git push." ], "afterMarkdowns": [ - "Ка-бум!. Ми запушили наші зміни у віддалений `master`, незважаючи на те, що локальна гілка називалась зовсім по-іншому." + "Ка-бум!. Ми запушили наші зміни у віддалений `main`, незважаючи на те, що локальна гілка називалась зовсім по-іншому." ], - "command": "git checkout -b foo o/master; git commit; git push", + "command": "git checkout -b foo o/main; git commit; git push", "beforeCommand": "git clone" } }, @@ -1294,11 +1542,11 @@ exports.level = { "", "Інший спосіб вказати за якою віддаленою гілкою слідкувати -- просто використовувати опцію `git branch -u`. Виконання", "", - "`git branch -u o/master foo`", + "`git branch -u o/main foo`", "", - "заставить гілку `foo` слідкувати за `o/master`. Якщо `foo` є поточною гілкою, її можна навіть не вказувати:", + "заставить гілку `foo` слідкувати за `o/main`. Якщо `foo` є поточною гілкою, її можна навіть не вказувати:", "", - "`git branch -u o/master`", + "`git branch -u o/main`", "" ] } @@ -1312,7 +1560,7 @@ exports.level = { "afterMarkdowns": [ "Як і перший спосіб, але своя окрема команда." ], - "command": "git branch -u o/master foo; git commit; git push", + "command": "git branch -u o/main foo; git commit; git push", "beforeCommand": "git clone; git checkout -b foo" } }, @@ -1320,7 +1568,243 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Гаразд! На цьому рівні збережімо свою роботу у віддалену гілку `master` *без* переходу на локальну `master`. Про решту здогадайся сам, раз ти вже дойшов до цього рівня :P" + "Гаразд! На цьому рівні збережімо свою роботу у віддалену гілку `main` *без* переходу на локальну `main`. Про решту здогадайся сам, раз ти вже дойшов до цього рівня :P" + ] + } + } + ] + }, + "vi": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Theo dõi nhánh từ xa", + "", + "Trong những bài học vừa qua có một điểu có vẻ như là \"ma thuật\" đó là git lại biết được nhánh `main` có liên kết đến nhánh `o/main`. Đúng là chúng có tên tương tự và nhánh `main` ở kho chứa từ xa có kết nối đến nhánh `main` ở kho chứa địa phương có vẻ như là hợp lý, nhưng kết nối này được thể hiện rõ ràng trong 2 trường hợp:", + "", + "* Trong quá trình thực hiện thao tác kéo, các commit được tải xuống nhánh `o/main` và sau đó *hợp nhất* vào nhánh `main`. Mục tiêu hợp nhất dược ngầm định bởi kết nối này.", + "* Trong quá trình thực hiện thao tác đẩy, thảnh quả trên nhánh `main` được đẩy lên nhánh `main` từ xa (sau dó được biểu thị bằng nhánh `o/main` ở kho chứa địa phương). *Đích đến* của lệnh đẩy được xác định bằng kết nối giữa nhánh `main` và nhánh `o/main`.", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Theo dõi từ xa", + "", + "Nói tóm lại, kết nối giữa nhánh `main` và nhánh `o/main` đơn giản được giải thích bằng thuộc tính \"theo dõi từ xa\" (\"remote tracking\") của các nhánh. Nhánh `main` được thiết lập để theo dõi nhánh `o/main` -- Điều này có nghĩa là nhánh `main` được chỉ định đích của lệnh đẩy và mục tiêu hợp nhất sau khi kéo.", + "", + "Có thể bạn sẽ thắc mắc rằng tại sao thuộc tính này được thiết lập lên nhánh `main` trong khi bạn chẳng hề chạy một câu lệnh nào chỉ định điều này. Chà, khi bạn dùng git để nhân bản kho chứa, thì thuộc tính này đã được tự động thiết lập cho bạn rồi. ", + "", + "Trong quá trình thực hiện nhân bản, git tạo ra nhánh từ xa trên kho chứa địa phương cho tất cả các nhánh trên kho chứa từ xa (các nhánh như `o/main`). Sau đó nó sẽ tạo một nhánh địa phương theo dõi nhánh hoạt dộng hiện tại của kho chứa từ xa, đa phần các trường hợp là nhánh `main`.", + "", + "Một khi quá trình nhân bản hoàn thành, bạn sẽ chỉ có một nhánh địa phương (để bạn không thấy quá tải) nhưng bạn có thể thấy tất cả các nhánh trên kho chứa từ xa (phòng trường hợp bạn thấy tò mò). Đây là phương án tối ưu!", + "", + "Điều này giải thích việc sau khi nhân bản bạn có thể thấy dòng lệnh sau xuất hiện:", + "", + " local branch \"main\" set to track remote branch \"o/main\"" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Tôi có thể tự chỉ định chứ?", + "", + "Tất nhiên là được chứ! Bạn có thế khiến bất kỳ nhánh nào theo dõi nhánh `o/main`, và nếu bạn làm vậy, nhánh đó sẽ được được chỉ định đích của lệnh đẩy và mục tiêu hợp nhất giống như nhánh `main`. Điều này có nghĩa là bạn có thể chạy lệnh `git push` trên nhánh có tên là `totallyNotMain` và thành quả của bạn sẽ được đẩy lên nhánh `main` ở kho chứa từ xa!", + "", + "Có 2 cách để thiết lập thuộc tính này. Cách đầu tiên là chuyển sang một nhánh mới từ một nhánh từ xa bằng cách thực hiện", + "", + "`git checkout -b totallyNotMain o/main`", + "", + "Tạo ra một nhánh mới `totallyNotMain` và thiết lập cho nó theo dõi nhánh `o/main`." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Nói vậy là đủ rồi, hãy xem thử một mô tả nào! Ta sẽ chuyển sang một nhánh tên là `foo` và thiết lập cho nó theo dõi nhánh `main` trên kho chứa từ xa." + ], + "afterMarkdowns": [ + "Như bạn đã thấy, chúng tôi đã sử dụng mục tiêu ngầm `o / main` để cập nhật nhánh` foo. Để ý rằng nhánh `main` không được cập nhật!!" + ], + "command": "git checkout -b foo o/main; git pull", + "beforeCommand": "git clone; git fakeTeamwork" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Điểu này cũng được áp dụng cho lệnh git push." + ], + "afterMarkdowns": [ + "Bùùm. Ta đã đẩy thành quả lên nhánh `main` ở kho chứa tù xa mặc dù nhánh của ta có tên hoàn toàn khác biệt" + ], + "command": "git checkout -b foo o/main; git commit; git push", + "beforeCommand": "git clone" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Cách thứ #2", + "", + "Cách khác để thiết lập theo dõi trên một nhánh đó là đơn giản sử dụng lệnh `git branch -u`. Thực hiện", + "", + "`git branch -u o/main foo`", + "", + "sẽ thiết lập nhánh `foo` theo dõi nhánh `o/main`. Nếu nhánh `foo` đang được `HEAD` trỏ tới bạn có thể bỏ tham số này:", + "", + "`git branch -u o/main`", + "" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Hãy xem thử cách khác để thiết lập theo dõi..." + ], + "afterMarkdowns": [ + "Y hệt như trước, nhưng lệnh này biểu hiện rõ ràng hơn. Tuyệt!" + ], + "command": "git branch -u o/main foo; git commit; git push", + "beforeCommand": "git clone; git checkout -b foo" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Được rồi! Ở cấp độ này hãy để thành quả lên nhánh `main` trên kho lưu trữ từ xa mà không chuyển sang nhánh `main` tại kho địa phương. Hãy tự tìm ra cách nhé, giờ là khóa học nâng cao rồi :P" + ] + } + } + ] + }, + "sl_SI": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Sledenje oddaljenih branchev", + "", + "Stvar, ki se je morda zdela \"čarobna\" v zadnjih lekcijah je, da je git vedel, da je `main` branch povezan z `o/main`. Seveda imata brancha podobno ime in morda deluje logično, da se poveže `main` branch na oddaljenem repotu z lokalnim `main` branchem, toda ta povezava je jasno predstavljena v dveh scenarijih:", + "", + "* Med pull operacijo so commiti preneseni na `o/main` in nato *zmergani* v `main` branch. Implicirana tarča merga je določena iz te povezave.", + "* Med push operacijo je delo iz `main` brancha naloženo na oddaljen `main` branch (ki je bil prej predstavljen kot `o/main` lokalno). *Destinacija* pusha je določena iz povezave med `main` in `o/main`.", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Sledenje oddaljenega repota", + "", + "Če povzamem, ta povezava med `main` in `o/main` je preprosto razložena z lastnostnjo \"oddaljenega sledenja\" branchev. `main` branch je nastavljen, da sledi `o/main` -- to pomeni, da obstaja impliciran cilj merga in impliciran cilj pusha za `main` branch.", + "", + "Morda se sprašuješ, kako se je nastavila ta lastnost na `main` branchu, čeprav nisi izvedel nobenega ukaza za to. No, ko kloniraš repo z gitom, je ta lastnost v bistvu nastavljena zate avtomatično. ", + "", + "Med kloniranjem git ustvari oddaljen branch za vsak branch na oddaljenem repotu (branchi kot `o/main`). Nato ustvari lokalen branch, ki sledi trenutno aktivnemu branchu na oddaljenem repotu, ki je v večini primerov `main`.", + "", + "Ko git clone zaključi, imaš samo en lokalen branch (da nisi zasipan), ampak lahko vidiš vse različne branche na oddaljenem repotu (če si zelo radoveden). Najboljše iz obeh svetov!", + "", + "To tudi razloži, zakaj lahko vidiš sledeč izpis ukaza med kloniranjem:", + "", + " local branch \"main\" set to track remote branch \"o/main\"" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Ali ga lahko določim sam?", + "", + "Seveda se da! Narediš lahko, da bilokateri branch sledi `o/main`. V tem primeru bo imel ta branch enak impliciran cilj za push in merge kot `main`. To pomeni, da lahko poženeš `git push` na branchu poimenovanem `splohNiMaster` in pushas svoje delo na `main` branch na oddaljenem repotu!", + "", + "Obstajata dva načina, da nastaviš to lastnost. Prvi je, da checkoutaš nov branch z uporabo oddaljenega brancha kot določeno referenca. Izvedba", + "", + "`git checkout -b splohNiMaster o/main`", + "", + "Ustvari nov branch imenovan `splohNiMaster` in nastavi, da sledi `o/main`." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Dovolj besedičenja, poglejmo primer! Checkoutali bomo nov branch poimenovan `foo` in ga nastavili, da sledi `main` na oddaljenem repotu." + ], + "afterMarkdowns": [ + "Kot lahko vidiš, smo uporabili impliciran cilj mergea `o/main`, da posodobi `foo` branch. Opazi, kako se main ne posodobi!!" + ], + "command": "git checkout -b foo o/main; git pull", + "beforeCommand": "git clone; git fakeTeamwork" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "To velja tudi za git push." + ], + "afterMarkdowns": [ + "Boom. Naše delo smo naložili na `main` na oddaljenem repotu, čeprav je ime našega brancha nekaj povsem drugega." + ], + "command": "git checkout -b foo o/main; git commit; git push", + "beforeCommand": "git clone" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Način #2", + "", + "Še en način, da se nastavi oddaljeno sledenje na branchu, je, da se uporabi `git branch -u` opcija. Izvedba", + "", + "`git branch -u o/main foo`", + "", + "bo nastavila `foo` branch, da sledi `o/main`. Če je `foo` trenutno checkoutan, ga lahko celo izpustiš", + "", + "`git branch -u o/main`", + "" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Poglejmo si na hitro še ta drug način določanja oddaljenega sledenja ..." + ], + "afterMarkdowns": [ + "Enako kot prej, le bolj natančno. Lepa!" + ], + "command": "git branch -u o/main foo; git commit; git push", + "beforeCommand": "git clone; git checkout -b foo" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Ok! Za to stopnjo pushajmo delo na `main` branch na oddaljenem repotu, medtem ko lokalno *nismo* na `masterju`. Ostalo prepustim tebi, ker je to vseeno napredna stopnja :P" ] } } diff --git a/src/style/font-awesome.css b/src/style/font-awesome.css index 377291bb..57f6f1fe 100644 --- a/src/style/font-awesome.css +++ b/src/style/font-awesome.css @@ -23,8 +23,8 @@ */ @font-face { font-family: "FontAwesome"; - src: url('./font/fontawesome-webfont.eot'); - src: url('./font/fontawesome-webfont.eot?#iefix') format('eot'), url('./font/fontawesome-webfont.woff') format('woff'), url('./font/fontawesome-webfont.ttf') format('truetype'), url('./font/fontawesome-webfont.svg#FontAwesome') format('svg'); + src: url('../assets/font/fontawesome-webfont.eot'); + src: url('../assets/font/fontawesome-webfont.eot?#iefix') format('eot'), url('../assets/font/fontawesome-webfont.woff') format('woff'), url('../assets/font/fontawesome-webfont.ttf') format('truetype'), url('../assets/font/fontawesome-webfont.svg#FontAwesome') format('svg'); font-weight: normal; font-style: normal; } @@ -301,4 +301,3 @@ li[class^="icon-"].icon-large:before, li[class*=" icon-"].icon-large:before { .icon-paste:before { content: "\f0ea"; } .icon-user-md:before { content: "\f200"; } - diff --git a/src/style/main.css b/src/style/main.css index a5ee34cf..cd15030a 100644 --- a/src/style/main.css +++ b/src/style/main.css @@ -10,7 +10,7 @@ body { } html, body { - font-family: Monaco, Courier, monospace; + font-family: Menlo, Monaco, Consolas, 'Droid Sans Mono', monospace; color: #eee; } @@ -72,6 +72,10 @@ body, display: -ms-flexbox; } +.contentHolder { + display: flex; +} + body, .flex1 { -webkit-box-flex: 1; @@ -121,7 +125,7 @@ body, -webkit-box-align: center; -moz-box-align: center; -ms-flex-align: center; - justify-content : center; + justify-content: center; } .startAlign { @@ -253,7 +257,15 @@ body.hgMode .visBackgroundColor { #interfaceWrapper { min-width: 600px; - min-height: 600px; + min-height: 400px; +} + +div.ui-draggable-handle { + cursor: grab; +} + +div.ui-draggable-dragging div.ui-draggable-handle { + cursor: grabbing; } div.canvasTerminalHolder > div.terminal-window-holder > div.wrapper { @@ -429,6 +441,10 @@ div.toolbar > div.controls div.box.flex1 div:hover { } +div.ui-draggable div.controls div.box.flex1 div { + cursor: pointer; +} + div.controls div.box.flex1 div.close { background-color: #fb625f; } @@ -493,6 +509,7 @@ div.reactCommandView p.commandLine span.icons i:first-child { p.commandLine span.icons i { opacity: 0; + line-height: 1em; } p.commandLine.inqueue span.icons i.icon-check-empty, @@ -548,7 +565,7 @@ p.commandLine span.prompt { #commandLineBar p.command { margin: 0; - margin-left: 12px; + margin-left: 20px; } #commandLineBar #commandTextField { @@ -562,6 +579,7 @@ p.commandLine span.prompt { margin: 10px; border-radius: 5px; box-shadow: 1px 0px 15px rgba(100, 100, 100, 1); + overflow: auto; } #commandLineHistory #terminal.scrolling { @@ -679,11 +697,12 @@ div.helperBar.show { -o-transform: translate3d(0,0,0); -ms-transform: translate3d(0,0,0); transform: translate3d(0,0,0); - height: 85px; + min-height: 85px; } div.helperBar.show.BaseHelperBar { height: auto; + min-height: auto; } #commandLineBar, @@ -770,6 +789,19 @@ li.rebaseEntry a#toggleButton { li.rebaseEntry.notPicked { opacity: 0.2; } + +li.rebaseEntry.notPicked span.showWhenPicked { + display: none; +} + +li.rebaseEntry span.showWhenNotPicked { + display: none; +} + +li.rebaseEntry.notPicked span.showWhenNotPicked { + display: inline; +} + /* Modal Views */ div.modalView.box.inFront.show { @@ -812,6 +844,7 @@ div.modalView.box.inFront.show { .modalView .terminal-window-holder { border-radius: 5px; max-width: 900px; + width: 90%; } .modalView .terminal-window { @@ -1149,6 +1182,12 @@ div.gitDemonstrationView { text-shadow: rgba(0,0,0,.4) 0 1px 0; color: white; + -webkit-touch-callout: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + vertical-align: middle; cursor: pointer; } @@ -1243,4 +1282,3 @@ div.gitDemonstrationView { border-top-color: #9bcbeb; background: #9bcbeb; } - diff --git a/src/style/rainbows.css b/src/style/rainbows.css index e7d1f072..7519f761 100644 --- a/src/style/rainbows.css +++ b/src/style/rainbows.css @@ -1,6 +1,6 @@ /* - * CSS animated rainbow dividers of awesome - * by Chris Heilmann @codepo8 and Lea Verou @leaverou + * CSS animated rainbow dividers of awesome + * by Chris Heilmann @codepo8 and Lea Verou @leaverou **/ /** @@ -8,28 +8,28 @@ */ @-moz-keyframes rainbowanim { - from { background-position:top left; } + from { background-position:top left; } to {background-position:top right; } } -@-webkit-keyframes rainbowanim { - from { background-position:top left; } - to { background-position:top right; } +@-webkit-keyframes rainbowanim { + from { background-position:top left; } + to { background-position:top right; } } -@-o-keyframes rainbowanim { - from { background-position:top left; } - to { background-position:top right; } +@-o-keyframes rainbowanim { + from { background-position:top left; } + to { background-position:top right; } } -@-ms-keyframes rainbowanim { - from { background-position:top left; } - to { background-position:top right; } +@-ms-keyframes rainbowanim { + from { background-position:top left; } + to { background-position:top right; } } -@-khtml-keyframes rainbowanim { - from { background-position:top left; } - to { background-position:top right; } +@-khtml-keyframes rainbowanim { + from { background-position:top left; } + to { background-position:top right; } } -@keyframes rainbowanim { - from { background-position:top left; } - to { background-position:top right; } +@keyframes rainbowanim { + from { background-position:top left; } + to { background-position:top right; } } .catchadream{ diff --git a/src/template.index.html b/src/template.index.html index c5312f4f..8f35f91b 100644 --- a/src/template.index.html +++ b/src/template.index.html @@ -1,4 +1,4 @@ - @@ -12,121 +12,11 @@ + - - - - - - + - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - Learn Git Branching - -
-
-
-
- -
-
-
-
- -
-
- $ -   -

-
- -
- -
-
- -
- - Git - - - Hg - -
- - - - -
- -
-
- -
-
- -
-
- - - - Fork me on GitHub - - - - - - {{jsDependencies}} - - + - + + + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + Learn Git Branching + +
+
+
+
+ +
+
+
+
+ +
+
+ $ +   +

+
+ +
+ +
+
+ +
+ + Git + + + Hg + +
+ + + + +
+ +
+
+ +
+
+ +
+
+ + + + + + - - - + Google analytics :-/ -->