├── .all-contributorsrc
├── .eslintrc.json
├── .github
└── workflows
│ └── learnpack-audit.yml
├── .gitignore
├── README.md
├── deploy-to-github.js
├── git-interactive.png
├── package-lock.json
├── package.json
├── preview.gif
├── public
├── css
│ ├── mediaQueries.css
│ └── style.css
├── favicon.ico
├── img
│ ├── logo-blue.png
│ ├── logo-short.png
│ ├── logo-smaller.png
│ └── logo.png
└── index.html
├── src
├── config
│ └── config.json
└── js
│ └── main.js
└── webpack.config.js
/.all-contributorsrc:
--------------------------------------------------------------------------------
1 | {
2 | "projectName": "git-interactive-tutorial",
3 | "projectOwner": "breatheco-de",
4 | "repoType": "github",
5 | "repoHost": "https://github.com",
6 | "files": [
7 | "README.md"
8 | ],
9 | "imageSize": 100,
10 | "commit": false,
11 | "contributors": [
12 | {
13 | "login": "alesanchezr",
14 | "name": "Alejandro Sanchez",
15 | "avatar_url": "https://avatars0.githubusercontent.com/u/426452?v=4",
16 | "profile": "https://alesanchezr.com",
17 | "contributions": [
18 | "code",
19 | "design",
20 | "doc",
21 | "review",
22 | "financial",
23 | "ideas"
24 | ]
25 | },
26 | {
27 | "login": "insomnux",
28 | "name": "insomnux",
29 | "avatar_url": "https://avatars1.githubusercontent.com/u/9019783?v=4",
30 | "profile": "https://github.com/insomnux",
31 | "contributions": [
32 | "translation"
33 | ]
34 | },
35 | {
36 | "login": "Jmsm19",
37 | "name": "Jorge Soto",
38 | "avatar_url": "https://avatars3.githubusercontent.com/u/7689660?v=4",
39 | "profile": "https://ve.linkedin.com/in/jorgemsm19",
40 | "contributions": [
41 | "code",
42 | "design"
43 | ]
44 | },
45 | {
46 | "login": "aliciaphes",
47 | "name": "Alicia Pérez",
48 | "avatar_url": "https://avatars1.githubusercontent.com/u/5432702?v=4",
49 | "profile": "http://www.linkedin.com/in/aliciapr",
50 | "contributions": [
51 | "translation"
52 | ]
53 | }
54 | ]
55 | }
56 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "commonjs": true,
5 | "es6": true,
6 | "node": true
7 | },
8 | "parserOptions": {
9 | "ecmaFeatures": {
10 | "jsx": true
11 | },
12 | "sourceType": "module"
13 | },
14 | "rules": {
15 | "no-const-assign": "warn",
16 | "no-this-before-super": "warn",
17 | "no-undef": "warn",
18 | "no-unreachable": "warn",
19 | "no-unused-vars": "warn",
20 | "constructor-super": "warn",
21 | "valid-typeof": "warn"
22 | }
23 | }
--------------------------------------------------------------------------------
/.github/workflows/learnpack-audit.yml:
--------------------------------------------------------------------------------
1 | # This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
3 |
4 | name: Learnpack audit
5 |
6 | on:
7 | push:
8 | branches: [ main ]
9 | pull_request:
10 | branches: [ main ]
11 |
12 | jobs:
13 | build:
14 |
15 | runs-on: ubuntu-latest
16 |
17 | strategy:
18 | matrix:
19 | node-version: [20.x]
20 | # See supported Node.js release schedule at https://nodejs.org/en/about/releases/
21 |
22 | steps:
23 | - uses: actions/checkout@v2
24 | - name: Use Node.js ${{ matrix.node-version }}
25 | uses: actions/setup-node@v2
26 | with:
27 | node-version: ${{ matrix.node-version }}
28 | - run: npm install @learnpack/learnpack@latest -g
29 | - run: learnpack audit
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | dist/
3 | public/bundle.js
4 | public/bundle.js.map
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
Git Interactive Tutorial (beta)
7 |
8 |
9 | 
10 |
11 | Learning git can be hard without the right tutorial, hopefully this guided tour will point you in the right direction. :bowtie:
12 |
13 | Just [click here](https://4GeeksAcademy.github.io/git-interactive-tutorial) to start learning!
14 |
15 | **Note**: a very similar tutorial was published on [try.github.com](https://try.github.com) but it was deleted for some reason :disappointed:, that is why at 4Geeks Academy we decided to replicate it and open source it to the community! :tada: :confetti_ball: :boom: :clap:
16 |
17 | ### :star: Give it a start if you like it!
18 |
19 | ### :exclamation: Report errors, misspells or give us suggestions [here](https://github.com/4GeeksAcademy/git-interactive-tutorial/issues).
20 |
21 | 
22 |
23 | ## Contributors
24 |
25 | Thanks goes to these wonderful people ([emoji key](https://github.com/kentcdodds/all-contributors#emoji-key)):
26 |
27 |
28 |
29 | | [
Alejandro Sanchez](https://alesanchezr.com)
[💻](https://github.com/breatheco-de/git-interactive-tutorial/commits?author=alesanchezr "Code") [🎨](#design-alesanchezr "Design") [📖](https://github.com/breatheco-de/git-interactive-tutorial/commits?author=alesanchezr "Documentation") [👀](#review-alesanchezr "Reviewed Pull Requests") [💵](#financial-alesanchezr "Financial") [🤔](#ideas-alesanchezr "Ideas, Planning, & Feedback") | [
insomnux](https://github.com/insomnux)
[🌍](#translation-insomnux "Translation") | [
Jorge Soto](https://ve.linkedin.com/in/jorgemsm19)
[💻](https://github.com/breatheco-de/git-interactive-tutorial/commits?author=Jmsm19 "Code") [🎨](#design-Jmsm19 "Design") | [
Alicia Pérez](http://www.linkedin.com/in/aliciapr)
[🌍](#translation-aliciaphes "Translation") |
30 | | :---: | :---: | :---: | :---: |
31 |
32 |
33 | This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
34 |
--------------------------------------------------------------------------------
/deploy-to-github.js:
--------------------------------------------------------------------------------
1 | var ghpages = require('gh-pages');
2 | var Console = require('bc-console');
3 | var webpack = require('webpack');
4 | var path = require('path');
5 | var fs = require('fs');
6 |
7 | var remoteOriginUrl = require('remote-origin-url');
8 | var gh = require('parse-github-url');
9 |
10 | if (!fs.existsSync(path.resolve(__dirname,'.git'))){
11 | Console.error("No repository found on this project");
12 | Console.help("Follow this steps to create a new repository for your project: http://kbroman.org/github_tutorial/pages/init.html");
13 | return;
14 | }
15 |
16 | const origin = remoteOriginUrl.sync();
17 | if(!origin || origin==''){
18 | Console.error("No remote origin has been found on this repository");
19 | Console.help(`Check your remote by doing:
20 | $ git remote get-url origin
21 |
22 | Add your remote by doing:
23 | $ git remote add origin
24 | `);
25 | return;
26 | }
27 | Console.info("The remote was found successfully, starting the deploy from here: "+origin);
28 |
29 | const repository = gh(origin);
30 | const compiler = webpack(require(path.resolve(__dirname, 'webpack.config.js')));
31 | compiler.run((err, stats) => {
32 | if (err || stats.hasErrors()) {
33 | console.log(stats.toString({
34 | colors: true
35 | }));
36 | Console.error("There was an error compiling, review above");
37 | return;
38 | }
39 | Console.success("Your code compiled successfully, proceding to deploy...");
40 | ghpages.publish('public', function(err) {
41 | if(err){
42 | console.error(err);
43 | Console.error("There was an error publishing your website");
44 | return;
45 | }
46 | //https://.github.io/
47 | Console.success(`Your website has been deployed successfully here: https://${repository["owner"]}.github.io/${repository["name"]}`);
48 | });
49 | });
--------------------------------------------------------------------------------
/git-interactive.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/4GeeksAcademy/git-interactive-tutorial/2ccd6a7fa4b04ef56fd22e8af7e73b5309d67151/git-interactive.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "githubtut",
3 | "version": "1.0.0",
4 | "description": "Git tutorial",
5 | "main": "index.html",
6 | "dependencies": {
7 | "font-awesome": "^4.7.0",
8 | "is-fullwidth-code-point": "^1.0.0",
9 | "number-is-nan": "^1.0.1",
10 | "object-assign": "^4.1.1",
11 | "sweetalert": "^1.1.3"
12 | },
13 | "devDependencies": {
14 | "all-contributors-cli": "^5.4.1",
15 | "babel-core": "^6.26.0",
16 | "babel-loader": "^7.1.2",
17 | "babel-preset-env": "^1.6.0",
18 | "babel-preset-es2015": "^6.24.1",
19 | "bc-console": "0.0.2",
20 | "gh-pages": "^2.0.1",
21 | "parse-github-url": "^1.0.2",
22 | "remote-origin-url": "^1.0.0",
23 | "webpack": "^4.23.1",
24 | "webpack-cli": "^3.1.2",
25 | "webpack-dev-server": "^3.1.10"
26 | },
27 | "scripts": {
28 | "test": "echo \"Error: no test specified\" && exit 1",
29 | "c9": "webpack-dev-server --mode development --open --host $IP --port $PORT",
30 | "build": "webpack --mode production",
31 | "deploy": "node deploy-to-github.js",
32 | "contributors:add": "all-contributors add",
33 | "contributors:generate": "all-contributors generate"
34 | },
35 | "repository": {
36 | "type": "git",
37 | "url": "git+https://Manten@bitbucket.org/Manten/githubtut.git"
38 | },
39 | "keywords": [
40 | "tutorial"
41 | ],
42 | "author": "Manten-Dev",
43 | "license": "ISC",
44 | "homepage": "https://bitbucket.org/Manten/githubtut#readme"
45 | }
--------------------------------------------------------------------------------
/preview.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/4GeeksAcademy/git-interactive-tutorial/2ccd6a7fa4b04ef56fd22e8af7e73b5309d67151/preview.gif
--------------------------------------------------------------------------------
/public/css/mediaQueries.css:
--------------------------------------------------------------------------------
1 | @media screen and (max-width: 940px) {
2 | body {
3 | font-size: 16px !important;
4 | }
5 |
6 | .title {
7 | font-size: .8rem !important;
8 | padding: 12px 5px !important;
9 | }
10 |
11 | .repo-status > div {
12 | font-size: .8rem !important;
13 | }
14 |
15 | #instrucciones {
16 | padding-top: 10px;
17 | }
18 |
19 | #instrucciones .tareas p {
20 | font-size: .94rem !important;
21 | }
22 |
23 | .comando {
24 | font-size: .8rem;
25 | }
26 |
27 | #repository .repo-status ul {
28 | margin-top: 5px;
29 | margin-left: 5px;
30 | width: 100%;
31 | }
32 |
33 | #repository ul li > ul {
34 | margin-top: 1px !important;
35 | margin-left: 5px !important;
36 | margin-bottom: 10px;
37 | }
38 |
39 | #repository .repo-status li {
40 | width: 100% !important;
41 | -webkit-user-select: none;
42 | -moz-user-select: none;
43 | -ms-user-select: none;
44 | user-select: none;
45 | margin-top: 2px;
46 | }
47 |
48 | #repository .repo-status li::before {
49 | font-family: FontAwesome;
50 | margin-right: 10px;
51 | font-size: 1rem;
52 | }
53 |
54 | .console-area {
55 | padding: 10px 20px !important;
56 | }
57 | }
58 |
59 | @media screen and (max-width: 749px) {
60 | i.hide-repo {
61 | visibility: hidden !important;
62 | }
63 |
64 | .only-mobile {
65 | display: block;
66 | }
67 |
68 | main {
69 | margin: 0 auto;
70 | padding: 0;
71 | width: 100%;
72 | }
73 |
74 | #area-practica {
75 | margin: 10px 10px 0 10px;
76 | }
77 |
78 | .main-menu {
79 | display: none;
80 | width: 290px !important;
81 | }
82 |
83 | a.logo-link {
84 | background: url('../img/logo.png') no-repeat center;
85 | background-size: contain;
86 | width: 150px !important;
87 | margin-left: 30px;
88 | }
89 |
90 | .expanded {
91 | display: block !important;
92 | width: 290px;
93 | overflow: visible;
94 | overflow-y: auto;
95 | padding-bottom: 40px;
96 | }
97 |
98 | #showNavbar {
99 | padding: 0;
100 | margin-top: 10px;
101 | padding: 3px 5px 5px 10px;
102 | width: 48px;
103 | height: 40px;
104 | position: fixed;
105 | color: #fbfbfb;
106 | background: #434343;
107 | border-right: 1px solid #666;
108 | border-top: 1px solid #666;
109 | border-bottom: 1px solid #666;
110 | top: 0;
111 | border-top-right-radius: 3px;
112 | border-bottom-right-radius: 3px;
113 | }
114 |
115 | #showNavbar::before {
116 | width: 42px ;
117 | height: 42px;
118 | font-family: FontAwesome;
119 | content: "\f0c9";
120 | font-size: 2rem;
121 | width: 100%;
122 | text-align: center;
123 | vertical-align: middle;
124 | }
125 |
126 | #leccion {
127 | -webkit-box-orient: vertical !important;
128 | -webkit-box-direction: normal !important;
129 | -ms-flex-direction: column !important;
130 | flex-direction: column !important;
131 | }
132 |
133 | #leccion > div {
134 | width: 100%;
135 | }
136 |
137 | .console-area,
138 | textarea {
139 | font-size: .7rem !important;
140 | }
141 |
142 | .container {
143 | width: 100%
144 | }
145 |
146 | #myProgress {
147 | position: fixed;
148 | width: 100%;
149 | }
150 |
151 | button.comando {
152 | font-size: .7rem !important;
153 | }
154 |
155 | #repository {
156 | margin-left: 0;
157 | margin-bottom: 10px;
158 | font-size: .8rem !important;
159 | }
160 |
161 | #repository .header {
162 | width: 100% !important;
163 | margin-right: 0;
164 | }
165 |
166 | #repository .header .buttons {
167 | width: 20%;
168 | padding: 6px;
169 | }
170 |
171 | #repository .repo-status {
172 | display: -webkit-box;
173 | display: -ms-flexbox;
174 | display: flex;
175 | -webkit-box-orient: vertical;
176 | -webkit-box-direction: normal;
177 | -ms-flex-direction: column;
178 | flex-direction: column;
179 | }
180 |
181 | #repository .repo-status .staged,
182 | #repository .repo-status .repo-folder,
183 | #repository .repo-status .commits {
184 | width: 100%;
185 | min-height: 100px;
186 | -webkit-box-shadow: 0 -1px 1px 1px #aaa inset;
187 | box-shadow: 0 -1px 1px 1px #aaa inset;
188 | }
189 |
190 | #repository .repo-status .commits {
191 | border-radius: 0 !important;
192 | }
193 |
194 | li.folder:active {
195 | background-color: transparent;
196 | }
197 |
198 | .column-1, .column-2 {
199 | width: 100% !important;
200 | }
201 |
202 | .column-2 {
203 | margin-top: 10px;
204 | }
205 |
206 | button.comando {
207 | left: 0;
208 | }
209 |
210 | button.comando:active {
211 | top: 1px;
212 | left: 0;
213 | }
214 |
215 | footer {
216 | font-size: .7rem !important;
217 | margin-top: 0px;
218 | -webkit-box-orient: vertical;
219 | -webkit-box-direction: normal;
220 | -ms-flex-direction: column;
221 | flex-direction: column;
222 | -ms-flex-pack: distribute;
223 | justify-content: space-around;
224 | }
225 |
226 | footer > * {
227 | margin: 0 auto!important;
228 | }
229 | }
--------------------------------------------------------------------------------
/public/css/style.css:
--------------------------------------------------------------------------------
1 | /* =================================
2 | GENERALES
3 | =================================== */
4 | * {
5 | padding: 0;
6 | margin: 0;
7 | -webkit-box-sizing: border-box;
8 | box-sizing: border-box;
9 | }
10 |
11 | .only-mobile {
12 | display: none;
13 | }
14 |
15 | ::-webkit-scrollbar {
16 | display: none;
17 | }
18 |
19 | html {
20 | width: 100vw !important;
21 | overflow-x: auto;
22 | overflow-y: visible;
23 | }
24 |
25 | body {
26 | opacity: 0;
27 | height: 100vh !important;
28 | display: -webkit-box;
29 | display: -ms-flexbox;
30 | display: flex;
31 | -webkit-box-orient: vertical;
32 | -webkit-box-direction: normal;
33 | -ms-flex-direction: column;
34 | flex-direction: column;
35 | font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
36 | font-size: 20px;
37 | color: #333;
38 | -webkit-transition: opacity 1s;
39 | transition: opacity 1s;
40 | overflow-x: hidden !important;
41 | overflow-y: visible !important;
42 | }
43 |
44 | main {
45 | position: relative;
46 | -webkit-box-flex: 1;
47 | -ms-flex: 1;
48 | flex: 1;
49 | background: #fbfbfb;
50 | margin-left: 59px;
51 | display: -webkit-box;
52 | display: -ms-flexbox;
53 | display: flex;
54 | -webkit-box-orient: vertical;
55 | -webkit-box-direction: normal;
56 | -ms-flex-direction: column;
57 | flex-direction: column;
58 | }
59 |
60 | main:after {
61 | content: " ";
62 | width: 100%;
63 | opacity: .9;
64 | z-index: 9;
65 | -webkit-transition: all .2s linear;
66 | transition: all .2s linear;
67 | position: absolute;
68 | }
69 |
70 | .main-menu.expanded + main:after {
71 | height: 100vh;
72 | background-color: #212121;
73 | }
74 |
75 | .container {
76 | width: 80%;
77 | max-width: 1024px;
78 | margin: 0 auto;
79 | }
80 |
81 | #area-practica {
82 | -webkit-box-flex: 1;
83 | -ms-flex: 1;
84 | flex: 1;
85 | display: -webkit-box;
86 | display: -ms-flexbox;
87 | display: flex;
88 | -webkit-box-orient: vertical;
89 | -webkit-box-direction: normal;
90 | -ms-flex-direction: column;
91 | flex-direction: column;
92 | height: 100%;
93 | }
94 |
95 | .hidden {
96 | display: none;
97 | }
98 |
99 | .invisible {
100 | opacity: 0;
101 | }
102 |
103 | h1 {
104 | text-align: center;
105 | }
106 |
107 | a {
108 | text-decoration: none;
109 | }
110 |
111 | li {
112 | list-style: none !important;
113 | }
114 |
115 | .red {
116 | color: #f44336;
117 | }
118 |
119 | .green {
120 | color: #64c53d;
121 | }
122 |
123 | .yellow {
124 | color: yellow;
125 | }
126 |
127 | .blue {
128 | color: #2196F3;
129 | }
130 |
131 | .no-json {
132 | margin-top: 50px;
133 | text-align: center;
134 | }
135 |
136 | /* =================================
137 | NAVIGATION
138 | =================================== */
139 |
140 | nav ul,
141 | nav li {
142 | outline: 0;
143 | margin: 0;
144 | padding: 0;
145 | }
146 |
147 | .main-menu {
148 | display: block;
149 | z-index: 10;
150 | background: #434343 !important;
151 | border-right: 1px solid #e5e5e5;
152 | position: fixed;
153 | top: 0;
154 | bottom: 0;
155 | height: 100vh;
156 | padding-bottom: 40px;
157 | left: 0;
158 | width: 59px;
159 | overflow: hidden;
160 | -webkit-transform: translateZ(0) scale(1,1);
161 | transform: translateZ(0) scale(1,1);
162 | -webkit-user-select: none;
163 | -moz-user-select: none;
164 | -ms-user-select: none;
165 | user-select: none;
166 | border: none;
167 |
168 | -webkit-transition: width .2s linear;
169 |
170 | transition: width .2s linear;
171 | }
172 |
173 | .main-menu.expanded {
174 | display: block !important;
175 | width: 330px;
176 | overflow: visible;
177 | overflow-y: auto;
178 | }
179 |
180 | .main-menu.main-menu.expanded + main {
181 | background-color: black;
182 | height: 10vh;
183 | z-index: 9;
184 | }
185 |
186 | a.logo-link {
187 | display: block;
188 | background: url('../img/logo-smaller.png') no-repeat center;
189 | background-size: contain;
190 | display: block;
191 | margin: 15px 3px 20px 3px;
192 | width: 53px;
193 | height: 53px;
194 | }
195 |
196 | .main-menu a.logo-link:link,
197 | .main-menu a.logo-link:hover,
198 | .main-menu a.logo-link:active {
199 | outline: none;
200 | }
201 |
202 | .main-menu.expanded a.logo-link {
203 | background: url('../img/logo.png') no-repeat center;
204 | background-size: contain;
205 | width: 200px !important;
206 | }
207 |
208 | .main-menu > ul {
209 | margin: 7px 0;
210 | }
211 |
212 | .main-menu li {
213 | position: relative;
214 | display: block;
215 | width:330px;
216 | }
217 |
218 | .main-menu li > a {
219 | position: relative;
220 | color: #ccc;
221 | font-size: 14px;
222 | -webkit-transform: translateZ(0) scale(1,1);
223 | transform: translateZ(0) scale(1,1);
224 | -webkit-transition: all .1s linear;
225 | transition: all .1s linear;
226 | display: -webkit-box;
227 | display: -ms-flexbox;
228 | display: flex;
229 | -webkit-box-orient: horizontal;
230 | -webkit-box-direction: normal;
231 | -ms-flex-direction: row;
232 | flex-direction: row;
233 | }
234 |
235 | .main-menu.main-menu.expanded li:hover > a {
236 | cursor: pointer;
237 | color: #FFF;
238 | background-color: #555;
239 | padding-left: 5px;
240 | }
241 |
242 | .main-menu .nav-text {
243 | width: 100%;
244 | position: relative;
245 | vertical-align: middle;
246 | text-transform: uppercase;
247 | padding: 8px 8px 8px 0;
248 | vertical-align: middle;
249 | }
250 |
251 | .main-menu .nav-text::before {
252 | font-family: FontAwesome;
253 | height: 100%;
254 | width: 59px !important;
255 | text-align: center;
256 | vertical-align: middle;
257 | font-size: 20px;
258 | }
259 |
260 | .main-menu .nav-text.completed::before {
261 | content: "\f00c";
262 | color: #4CAF50;
263 | }
264 |
265 | .main-menu .nav-text.learning::before {
266 | content: "\f212";
267 | color: #148FCB;
268 | }
269 |
270 | /* =================================
271 | PROGRESS BAR
272 | =================================== */
273 |
274 | #myProgress {
275 | height: 7px;
276 | width: 100% !important;
277 | background-color: #f44336;
278 | -webkit-box-shadow: 0 0 10px #434343 inset;
279 | box-shadow: 0 0 10px #434343 inset;
280 | }
281 |
282 | #myBar {
283 | width: 0%;
284 | height: 100%;
285 | background-color: #1976D2;
286 | -webkit-transition: width 1s;
287 | transition: width 1s;
288 | }
289 |
290 | /* =================================
291 | AREA DE INSTRUCCIONES
292 | =================================== */
293 |
294 | #leccion {
295 | -webkit-box-flex: 1;
296 | -ms-flex: 1;
297 | flex: 1;
298 | display: -webkit-box;
299 | display: -ms-flexbox;
300 | display: flex;
301 | -webkit-box-orient: horizontal;
302 | -webkit-box-direction: normal;
303 | -ms-flex-direction: row;
304 | flex-direction: row;
305 | -ms-flex-wrap: nowrap;
306 | flex-wrap: nowrap;
307 | -ms-flex-line-pack: justify;
308 | align-content: space-between;
309 | }
310 |
311 | #leccion .column-1 {
312 | display: -webkit-box;
313 | display: -ms-flexbox;
314 | display: flex;
315 | -webkit-box-orient: vertical;
316 | -webkit-box-direction: normal;
317 | -ms-flex-direction: column;
318 | flex-direction: column;
319 | width: 70%;
320 | -webkit-transition: width 1s;
321 | transition: width 1s;
322 | }
323 |
324 | #leccion .column-2 {
325 | width: 30%;
326 | }
327 |
328 | #leccion + div {
329 | padding: 10px;
330 | }
331 |
332 | #instrucciones {
333 | background-color: #FBFBFB;
334 | color: #434343;
335 | -webkit-box-flex: 3;
336 | -ms-flex: 3;
337 | flex: 3;
338 | padding: 30px 20px 10px 20px;
339 | min-height: 300px;
340 | display: -webkit-box;
341 | display: -ms-flexbox;
342 | display: flex;
343 | -webkit-box-orient: vertical;
344 | -webkit-box-direction: normal;
345 | -ms-flex-direction: column;
346 | flex-direction: column;
347 | max-width: 1300px;
348 | }
349 |
350 | #instrucciones a:link,
351 | #instrucciones a:visited {
352 | color: #1976D2;
353 | }
354 |
355 | #instrucciones > #instruccion {
356 | padding: 5px 0;
357 | text-transform: uppercase;
358 | }
359 |
360 | .tareas > p {
361 | padding: 8px 0;
362 | font-size: 1.1rem;
363 | }
364 |
365 | .comando {
366 | width: -webkit-fit-content;
367 | width: -moz-fit-content;
368 | width: fit-content;
369 | outline: none;
370 | margin-top: 10px;
371 | padding: 10px;
372 | border: none;
373 | font-size: .9rem;
374 | letter-spacing: 1px;
375 | font-family: 'Source Code Pro', monospace;
376 | background-color: #37474F;
377 | position: relative;
378 | color: #eee;
379 | margin-top: auto;
380 | width: 100%;
381 | text-align: left;
382 | }
383 |
384 | .comando::before {
385 | font-family: FontAwesome;
386 | content: '\f120';
387 | margin-right: 15px;
388 | }
389 |
390 | .comando:hover {
391 | opacity: .9;
392 | cursor: pointer;
393 | }
394 |
395 | .comando:active {
396 | position: relative;
397 | left: 0;
398 | top: 1px;
399 | }
400 |
401 | /* =================================
402 | TERMINAL AREA
403 | =================================== */
404 |
405 | div#terminal {
406 | padding: 0;
407 | -webkit-box-flex: 2;
408 | -ms-flex: 2;
409 | flex: 2;
410 | flex-grow: 2;
411 | height: 100%;
412 | display: -webkit-box;
413 | display: -ms-flexbox;
414 | display: flex;
415 | -webkit-box-orient: vertical;
416 | -webkit-box-direction: normal;
417 | -ms-flex-direction: column;
418 | flex-direction: column;
419 | }
420 |
421 | .console-area {
422 | height: 100%;
423 | display: -webkit-box;
424 | display: -ms-flexbox;
425 | display: flex;
426 | -webkit-box-orient: vertical;
427 | -webkit-box-direction: normal;
428 | -ms-flex-direction: column;
429 | flex-direction: column;
430 | font-size: .8rem !important;
431 |
432 | padding: 10px 30px;
433 | font-family: 'Source Code Pro', monospace;
434 | background-color: hsl(220, 13%, 18%);
435 | overflow-y: auto;
436 | overflow-x: hidden;
437 | color: #eee;
438 | font-size: .8rem;
439 | letter-spacing: .5px !important;
440 | }
441 |
442 | .console-area .line-marker {
443 | display: inline-block;
444 | background-size: contain;
445 | width: 20px !important;
446 | height: 20px !important;
447 | width: 100%;
448 | }
449 |
450 | .line-marker + p {
451 | display: inline-block;
452 | padding: 0 10px 5px 10px;
453 | margin: 0 !important;
454 | }
455 |
456 | .console-area .line-marker::before {
457 | background: url('../img/logo-blue.png')
458 | }
459 |
460 | .console-area .current-line,
461 | .console-area .line {
462 | width: 100%;
463 | margin-top: 15px;
464 | display: -webkit-box;
465 | display: -ms-flexbox;
466 | display: flex;
467 | -webkit-box-orient: horizontal;
468 | -webkit-box-direction: normal;
469 | -ms-flex-direction: row;
470 | flex-direction: row;
471 | }
472 |
473 | .console-area .line {
474 | margin-bottom: 15px;
475 | min-height: 18.4px;
476 | }
477 |
478 | .console-area > * {
479 | margin-top: 10px;
480 | width: 100%;
481 | }
482 |
483 | .console-area > p {
484 | min-height: 18.4px !important;
485 | content: " ";
486 | }
487 |
488 | .error {
489 | color: #fb8a8a;
490 | }
491 |
492 | .success {
493 | color: #64c53d;
494 | }
495 |
496 | .error, .success {
497 | margin-top: 5px;
498 | margin-left: 15px;
499 | }
500 |
501 | .console-area textarea {
502 | height: 43.4px;
503 | overflow: auto;
504 | font-family: 'Source Code Pro', monospace !important;
505 | width: 100%;
506 | resize: none;
507 | background-color: transparent;
508 | color: #eee;
509 | border: none;
510 | padding: 0 10px 5px 10px;
511 | line-height: 1.5;
512 | }
513 |
514 | .console-area textarea:focus {
515 | outline: none;
516 | }
517 |
518 | /* =================================
519 | REPO FOLDER STRUCTURE
520 | =================================== */
521 | #repository {
522 | position: relative;
523 | height: 100%;
524 | font-size: .9rem !important;
525 | color: #FFF;
526 | left: 0;
527 | }
528 |
529 | .show-repo {
530 | outline: none;
531 | color: #fbfbfb;
532 | position: absolute;
533 | top: 7px !important;
534 | right: 0 !important;
535 | padding: 3px 20px;
536 | height: 38.4px;
537 | width: 50px;
538 | z-index: 9;
539 | background-color: #424242;
540 | border: none;
541 | font-size: 1.5rem;
542 | }
543 |
544 | .show-repo:hover {
545 | background-color: #555 !important;
546 | cursor: pointer;
547 | }
548 |
549 | #repository .header {
550 | display: -webkit-box;
551 | display: -ms-flexbox;
552 | display: flex;
553 | -webkit-box-orient: horizontal;
554 | -webkit-box-direction: normal;
555 | -ms-flex-direction: row;
556 | flex-direction: row;
557 | height: 5%;
558 | width: 100%;
559 | background-color: #424242;
560 | }
561 |
562 | #repository .header i {
563 | width: 10%;
564 | padding: 3px 20px;
565 | font-size: 1.5rem;
566 | }
567 |
568 | #repository .header i:hover {
569 | background-color: #555;
570 | cursor: pointer;
571 | }
572 |
573 | #repository .header .title {
574 | width: 90%;
575 | font-weight: bold;
576 | padding: 5px 15px;
577 | text-align: left;
578 | -webkit-user-select: none;
579 | -moz-user-select: none;
580 | -ms-user-select: none;
581 | user-select: none;
582 | letter-spacing: 1px;
583 | font-size: 1.2rem;
584 | }
585 |
586 | #repository .repo-status {
587 | height: 95%;
588 | display: -webkit-box;
589 | display: -ms-flexbox;
590 | display: flex;
591 | -webkit-box-orient: vertical;
592 | -webkit-box-direction: normal;
593 | -ms-flex-direction: column;
594 | flex-direction: column;
595 | }
596 |
597 | .branch {
598 | color: orangered;
599 | }
600 |
601 | #repository .repo-status .staged,
602 | #repository .repo-status .repo-folder,
603 | #repository .repo-status .commits {
604 | height: 33.333%;
605 | width: 100%;
606 | padding: 5px 10px;
607 | color: #434343;
608 | overflow-y: auto;
609 | font-size: 1rem;
610 | background-color: #fbfbfb;
611 | -webkit-box-shadow: 1px 0 1px 0 #aaa inset;
612 | box-shadow: 1px 0 1px 0 #aaa inset;
613 | }
614 |
615 | #repository .repo-status ul {
616 | margin-top: 5px;
617 | margin-left: 5px;
618 | width: 100%;
619 | }
620 |
621 | #repository ul li > ul {
622 | margin-top: 0 !important;
623 | margin-left: 20px !important;
624 | margin-bottom: 10px;
625 | }
626 |
627 | #repository .repo-status li {
628 | width: 100% !important;
629 | margin-top: 2px;
630 | }
631 |
632 | #repository .repo-status li.commit {
633 | margin-top: 6px;
634 | }
635 |
636 | #repository .repo-status li::before {
637 | font-family: FontAwesome;
638 | margin-right: 6px !important ;
639 | font-size: 1.3rem;
640 | }
641 |
642 | #repository li.folder:hover {
643 | cursor: pointer;
644 | opacity: .7;
645 | }
646 |
647 | #repository li.folder::before {
648 | content: "\f07c";
649 | color: #CCB897;
650 | }
651 |
652 | #repository li.folder+ li.closed {
653 | display: none;
654 | }
655 |
656 | #repository li.file::before {
657 | color: #FF5722;
658 | content: "\f0f6";
659 | }
660 |
661 | #repository li.info::before {
662 | color: #f44336;
663 | content: "\f05a";
664 | }
665 |
666 | #repository .repo-status li.commit::before {
667 | font-family: FontAwesome;
668 | content: "\f113" !important;
669 | color: #9C27B0;
670 | }
671 |
672 | /* =================================
673 | FOOTER
674 | =================================== */
675 |
676 | footer {
677 | display: -webkit-box;
678 | display: -ms-flexbox;
679 | display: flex;
680 | -webkit-box-orient: horizontal;
681 | -webkit-box-direction: normal;
682 | -ms-flex-direction: row;
683 | flex-direction: row;
684 | -webkit-box-pack: justify;
685 | -ms-flex-pack: justify;
686 | justify-content: space-between;
687 | font-size: .8rem !important;
688 | padding: 0 13px 13px 13px;
689 | background-color: #434343;
690 | color: #EEE !important;
691 | z-index: 99;
692 | height: 45px;
693 | }
694 |
695 | footer > p {
696 | margin-top: 13px;
697 | margin-left: 50px;
698 | }
699 |
700 | footer a:link,
701 | footer a:visited {
702 | color: #EEE;
703 | }
704 |
705 | footer a:hover {
706 | font-weight: bold;
707 | }
708 |
709 | footer div {
710 | position: relative;
711 | height: 45px;
712 | display: flex;
713 | flex-direction: row;
714 | justify-content: space-between;
715 | }
716 |
717 | .coder {
718 | margin-top: 13px;
719 | margin-right: 75px;
720 | }
721 |
722 | #lang {
723 | background-color: #EEE;
724 | color: #1976D2;
725 | font-weight: bold;
726 | position: absolute;
727 | right: 0;
728 | top: 10px;
729 | width: 65px;
730 | padding:5px;
731 | border: 0;
732 | border-radius: 0;
733 | height: 25px;
734 | -webkit-appearance: none;
735 | }
736 |
737 | /* =================================
738 | ANIMACIONES
739 | =================================== */
740 |
741 | .typed {
742 | white-space: nowrap;
743 | overflow: hidden;
744 | -webkit-animation: type 4s steps(60, end);
745 | animation: type 4s steps(60, end);
746 | }
747 |
748 | @-webkit-keyframes type{
749 | from { width: 0; }
750 | }
751 |
752 | @keyframes type{
753 | from { width: 0; }
754 | }
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/4GeeksAcademy/git-interactive-tutorial/2ccd6a7fa4b04ef56fd22e8af7e73b5309d67151/public/favicon.ico
--------------------------------------------------------------------------------
/public/img/logo-blue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/4GeeksAcademy/git-interactive-tutorial/2ccd6a7fa4b04ef56fd22e8af7e73b5309d67151/public/img/logo-blue.png
--------------------------------------------------------------------------------
/public/img/logo-short.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/4GeeksAcademy/git-interactive-tutorial/2ccd6a7fa4b04ef56fd22e8af7e73b5309d67151/public/img/logo-short.png
--------------------------------------------------------------------------------
/public/img/logo-smaller.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/4GeeksAcademy/git-interactive-tutorial/2ccd6a7fa4b04ef56fd22e8af7e73b5309d67151/public/img/logo-smaller.png
--------------------------------------------------------------------------------
/public/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/4GeeksAcademy/git-interactive-tutorial/2ccd6a7fa4b04ef56fd22e8af7e73b5309d67151/public/img/logo.png
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Git Tutorial
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
25 |
26 |
27 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
1.X - Instrucciones
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
Presiona Enter para ingresar tus comandos.
45 |
46 |

47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
59 |
60 |
61 |
Root folder
62 |
63 |
64 |
Staged
65 |
66 |
67 |
Commits
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
90 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/src/config/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "config": {
3 | "repoName": "my_project",
4 | "_comment": "errorComando, in case of no command match",
5 | "errorComando": "command not found",
6 | "success": "Success!",
7 | "emptyFolderMessage": "No files in this folder yet",
8 | "emptyStageAreaMessage": "No files to commit",
9 | "emptyCommitsAreaMessage": "Nothing commited yet",
10 | "_comment2": "if user writes 'git', show following error",
11 | "errorMessages": [
12 | "usage: git [--version] [--exec-path[=<path>]]",
13 | " [-p|--paginate|--no-pager]",
14 | " [--git-dir=<path>] [--work-tree=<path>]",
15 | " [-c name=value] [--help]",
16 | " <command> [<args>]",
17 | " "
18 | ],
19 | "_comment3": "the following field must have the parragraph tag to work properly. You can add as many as you need.",
20 | "tutorialCompletedMessage": "Well done!
"
21 | },
22 | "lecciones": {
23 | "es": {
24 | "1": {
25 | "orden": "1",
26 | "titulo": "¿Quieres aprender a usar Git?",
27 | "tituloCorto": "¿Quieres aprender Git?",
28 | "tareas": [
29 | "Git es un sistema de control de versiones distribuido que permite a equipos de trabajo tratar con un mismo documento o código al mismo tiempo, evitando choques entre los miembros.",
30 | "En la terminal que puedes ver en pantalla hemos creado un repositorio, un contendor de archivos. Para inicializar un repositorio en Git debes escribir el siguiente comando: git init."
31 | ],
32 | "comando": "git init",
33 | "alert": "Did not create a Git repo",
34 | "successMessages": [
35 | "Initialized empty Git repository in /.git/"
36 | ],
37 | "repoStatus": {}
38 | },
39 | "2": {
40 | "orden": "2",
41 | "titulo": "Revisando el status del repositorio",
42 | "tituloCorto": "Revisando el status",
43 | "tareas": [
44 | "Bien hecho. Has logrado crear tu primer repositorio. Ahora en nuestro repositorio se ha creado una carpeta llamada /.git/. Si creas un repositorio en tu equipo, esta carpeta estará oculta. En ella se encuentran una serie de subdirectorios con archivos que contienen referencias a todos los cambios que han ocurrido en tu repositorio.",
45 | "Ahora, usando el comando git status veamos cuál es el estado actual de nuestro repositorio."
46 | ],
47 | "comando": "git status",
48 | "alert": "Did not use git status",
49 | "successMessages": [
50 | "# On branch master",
51 | "#",
52 | "# Initial commit",
53 | "#",
54 | "nothing to commit",
55 | "(create/copy files and use \"git add\" to track)"
56 | ],
57 | "repoStatus": {
58 | "branch": "master",
59 | "repoFolder": [
60 | { ".git": [ ] },
61 | "mi_plan.txt"
62 | ]
63 | }
64 | },
65 | "3": {
66 | "orden": "3",
67 | "titulo": "Agregar archivos y hacer commit",
68 | "tituloCorto": "Primer uso del repositorio",
69 | "tareas": [
70 | "Si a lo largo de este tutorial sientes que en tu terminal hay demasiado texto, puedes usar el comando clear para limpiar todo el contenido de ella.",
71 | "Sigamos. Imagina que agregas un nuevo archivo llamado mi_plan.txt a tu repositorio.",
72 | "Ahora, si usamos de nuevo el comando git status podrás notar que el estado de tu repositorio ha cambiado."
73 | ],
74 | "comando": "git status",
75 | "alert": "Did not use git status",
76 | "successMessages": [
77 | "# On branch master",
78 | "#",
79 | "# Initial commit",
80 | "#",
81 | "# Untracked files:",
82 | "# (use \"git add ...\" to include files)",
83 | "#",
84 | "# mi_plan.txt",
85 | "nothing added to commit",
86 | "but untracked files present",
87 | "(use 'git add' to track)"
88 | ],
89 | "repoStatus": {
90 | "branch": "master",
91 | "repoFolder": [
92 | { ".git": [ ] },
93 | "mi_plan.txt"
94 | ]
95 | }
96 | },
97 | "4": {
98 | "orden": "4",
99 | "titulo": "Haciendo cambios",
100 | "tituloCorto": "Haciendo cambios",
101 | "tareas": [
102 | "¿Notaste cómo el archivo mi_plan.txt apareció como untracked en la terminal?",
103 | "Eso significa que el archivo es nuevo y Git aún no está siguiendo sus cambios.",
104 | "Para que Git pueda seguir todos los cambios que se realicen en el archivo, primero debemos agregarlo a la zona de preparación o Stage con el comando git add [nombre del archivo]."
105 | ],
106 | "comando": "git add mi_plan.txt",
107 | "alert": "Did not add mi_plan.txt",
108 | "successMessages": [
109 | "¡Bien hecho! mi_plan.txt ha sido agregado al Stage"
110 | ],
111 | "repoStatus": {
112 | "branch": "master",
113 | "repoFolder": [
114 | { ".git": [ ] },
115 | "mi_plan.txt"
116 | ],
117 | "staged": [
118 | "mi_plan.txt"
119 | ]
120 | }
121 | },
122 | "5": {
123 | "orden": "5",
124 | "titulo": "Revisando los cambios",
125 | "tituloCorto": "Revisando los cambios",
126 | "tareas": [
127 | "¡Excelente! Ahora que git ya está pendiente de los cambios de nuestro archivo, podemos usar de nuevo el comando git status para asegurarnos de que todo está bien."
128 | ],
129 | "comando": "git status",
130 | "alert": "Did not use git status",
131 | "successMessages": [
132 | "# On branch master",
133 | "#",
134 | "# Initial commit",
135 | "#",
136 | "# Changes to be committed:",
137 | "# (use \"git rm --cached ...\" to unstage)",
138 | "#",
139 | "# new file: mi_plan.txt",
140 | "#"
141 | ],
142 | "repoStatus": {
143 | "branch": "master",
144 | "repoFolder": [
145 | { ".git": [ ] },
146 | "mi_plan.txt"
147 | ],
148 | "staged": [
149 | "mi_plan.txt"
150 | ]
151 | }
152 | },
153 | "6": {
154 | "orden": "6",
155 | "titulo": "Haciendo commit",
156 | "tituloCorto": "Haciendo commit",
157 | "tareas": [
158 | "Ahora con tu archivo preparado y en el Stage podemos seguir con el siguiente paso, hacer commit.",
159 | "Hacer commit es simplemente enviar nuestros cambios desde el Stage a nuestro repositorio. Si así quisieras, podrías agregar y quitar archivos del Stage antes de hacer commit.",
160 | "Para guardar tus cambios en el repositorio usamos el comando git commit -m seguido de un mensaje que describa los cambios que hemos realizado. En este caso, solo hemos agregado un nuevo archivo, así que solo escribiremos Agregar mi_plan.txt entre comillas."
161 | ],
162 | "comando": "git commit -m \"Agregar mi_plan.txt\"",
163 | "alert": "Did not use git commit",
164 | "successMessages": [
165 | "[master (root-commit) 20b5ccd] Agregar mi_plan.txt",
166 | "1 file changed, 1 insertion(+)",
167 | "create mode 100644 mi_plan.txt",
168 | " "
169 | ],
170 | "repoStatus": {
171 | "branch": "master",
172 | "repoFolder": [
173 | { ".git": [ ] },
174 | "mi_plan.txt"
175 | ],
176 | "commits": [
177 | "20b5ccd - Agregar mi_plan.txt"
178 | ]
179 | }
180 | },
181 | "7": {
182 | "orden": "7",
183 | "titulo": "Agregando varios archivos",
184 | "tituloCorto": "Agregando varios archivos",
185 | "tareas": [
186 | "Nuestro repositorio ya tiene un commit. Pero ahora, imagina que has estado trabajando todo el día en tu proyecto y has terminado creando varios archivos de texto. Usar el comando git add para agregarlos uno a uno es bastante fastidioso, ¿verdad? Pues Git nos ofrece un metodo un poco más comodo.",
187 | "Para ello usaremos el comando git add \"*.txt\" el cual agregará todos los archivos de texto que hayan sido editados en nuestro repositorio."
188 | ],
189 | "comando": "git add \"*.txt\"",
190 | "alert": "Did not use git add",
191 | "successMessages": [
192 | "Archivos agregados"
193 | ],
194 | "repoStatus": {
195 | "branch": "master",
196 | "repoFolder": [
197 | { ".git": [ ] },
198 | { "planes_septiembre" : [ "desarrollo.txt" ] },
199 | { "planes_octubre" : [ "maquetado.txt" ] },
200 | "reuniones_del_mes.txt",
201 | "mi_plan.txt"
202 | ],
203 | "staged": [
204 | { "planes_septiembre" : [ "desarrollo.txt" ] },
205 | { "planes_octubre" : [ "maquetado.txt" ] },
206 | "reuniones_del_mes.txt"
207 | ],
208 | "commits": [
209 | "20b5ccd - Agregar mi_plan.txt"
210 | ]
211 | }
212 | },
213 | "8": {
214 | "orden": "8",
215 | "titulo": "Revertir el Stage",
216 | "tituloCorto": "Git reset",
217 | "tareas": [
218 | "Así como git add envía tus archivos editados al Stage, existe el comando git reset que hace todo lo contrario. Retira los archivos del Stage.",
219 | "Este comando puede recibir los mismos argumentos que hemos visto hasta ahora con git add.",
220 | "Probemos retirando los archivos de texto que acabamos de agregar al Stage."
221 | ],
222 | "comando": "git reset",
223 | "alert": "Did not use git reset",
224 | "successMessages": [
225 | "Los archivos de texto ya no están en el Stage"
226 | ],
227 | "repoStatus": {
228 | "branch": "master",
229 | "repoFolder": [
230 | { ".git": [ ] },
231 | { "planes_septiembre" : [ "desarrollo.txt" ] },
232 | { "planes_octubre" : [ "maquetado.txt" ] },
233 | "reuniones_del_mes.txt",
234 | "mi_plan.txt"
235 | ],
236 | "commits": [
237 | "20b5ccd - Agregar mi_plan.txt"
238 | ]
239 | }
240 | },
241 | "9": {
242 | "orden": "9",
243 | "titulo": "Agregando archivos de nuevo",
244 | "tituloCorto": "Git add #2",
245 | "tareas": [
246 | "Como podrás notar nuestros archivos de texto ya no están en en la zona de preparación.",
247 | "Ahora, volvamos a agregarlos."
248 | ],
249 | "comando": "git add \"*.txt\"",
250 | "alert": "Did not use git add",
251 | "successMessages": [
252 | "Archivos agregados"
253 | ],
254 | "repoStatus": {
255 | "branch": "master",
256 | "repoFolder": [
257 | { ".git": [ ] },
258 | { "planes_septiembre" : [ "desarrollo.txt" ] },
259 | { "planes_octubre" : [ "maquetado.txt" ] },
260 | "reuniones_del_mes.txt",
261 | "mi_plan.txt"
262 | ],
263 | "staged": [
264 | { "planes_septiembre" : [ "desarrollo.txt" ] },
265 | { "planes_octubre" : [ "maquetado.txt" ] },
266 | "reuniones_del_mes.txt"
267 | ],
268 | "commits": [
269 | "20b5ccd - Agregar mi_plan.txt"
270 | ]
271 | }
272 | },
273 | "10": {
274 | "orden": "10",
275 | "titulo": "Volviendo a hacer commit",
276 | "tituloCorto": "Haciendo commit #2",
277 | "tareas": [
278 | "Hagamos un commit con los nuevos cambios.",
279 | "¿Qué te parece usar el mensaje Agregar todos los archivos de texto?"
280 | ],
281 | "comando": "git commit -m \"Agregar todos los archivos de texto\"",
282 | "alert": "Did not use git commit",
283 | "successMessages": [
284 | "[master (root-commit) 3852b4d]",
285 | "'Agregar todos los archivos de texto'",
286 | "3 file changed, 3 insertion(+)",
287 | "create mode 100644 desarrollo.txt",
288 | "create mode 100644 maquetado.txt",
289 | "create mode 100644 reuniones_del_mes.txt",
290 | " "
291 | ],
292 | "repoStatus": {
293 | "branch": "master",
294 | "repoFolder": [
295 | { ".git": [ ] },
296 | { "planes_septiembre" : [ "desarrollo.txt" ] },
297 | { "planes_octubre" : [ "maquetado.txt" ] },
298 | "reuniones_del_mes.txt",
299 | "mi_plan.txt"
300 | ],
301 | "commits": [
302 | "20b5ccd - Agregar mi_plan.txt",
303 | "3852b4d - Agregar todos los archivos de texto"
304 | ]
305 | }
306 | },
307 | "11": {
308 | "orden": "11",
309 | "titulo": "Revisando el historial con git log",
310 | "tituloCorto": "Usado git log",
311 | "tareas": [
312 | "¿Qué tal? Ya llevamos dos commits hasta ahora.",
313 | "Git nos ofrece un comando que permite revisar un historial con todos los commits que hemos hecho hasta el momento en orden cronológico. Este comando es git log"
314 | ],
315 | "comando": "git log",
316 | "alert": "Did not use git log",
317 | "successMessages": [
318 | "commit: 3852b4db1634463d0bb4d267edb7b3f9cd02ace1",
319 | "Author: 4Geeks Student ",
320 | "Date: Fri Sep 19 18:30:00 2017 -0400",
321 | " Agregar mi_plan.txt",
322 | " ",
323 | "commit: b652edfd888cd3d5e7fcb857d0dabc5a0fcb5e28",
324 | "Author: 4Geeks Student ",
325 | "Date: Thu Sep 18 18:00:32 2017 -0400",
326 | " Agregar todos los archivos de texto"
327 | ],
328 | "repoStatus": {
329 | "branch": "master",
330 | "repoFolder": [
331 | { ".git": [ ] },
332 | { "planes_septiembre" : [ "desarrollo.txt" ] },
333 | { "planes_octubre" : [ "maquetado.txt" ] },
334 | "reuniones_del_mes.txt",
335 | "mi_plan.txt"
336 | ],
337 | "commits": [
338 | "20b5ccd - Agregar mi_plan.txt",
339 | "3852b4d - Agregar todos los archivos de texto"
340 | ]
341 | }
342 | },
343 | "12": {
344 | "orden": "12",
345 | "titulo": "Manejando repositorios remotos",
346 | "tituloCorto": "Git remote",
347 | "tareas": [
348 | "Bien, ya hemos aprendido los comandos más básicos de Git. Ahora veamos su utilidad práctica. Imagina que quieres que otras personas tengan acceso a tu repositorio. Para lograr debes subir nuestro repositorio a una plataforma como GitHub que se encarga resguardar repositorios publicos y privados en sus servidores.",
349 | "Ahora, una vez creado un repositorio en GitHub tendremos que asociarlo a nuestro repositorio local, para ello usamos git remote add seguido del nombre con el cual queremos asociar el repositorio remoto que deseamos agregar y de su URL. Se acostumbra llamar al repositorio remoto principal origin, así que haremos eso. Y su URL es https://github.com/4geeksAcademy/project.git. Esta vez no son necesarias las comillas."
350 | ],
351 | "comando": "git remote add origin https://github.com/4geeksAcademy/project.git",
352 | "alert": "Did not use git remote add",
353 | "successMessages": [
354 | "Repositorio agregado con éxito"
355 | ],
356 | "repoStatus": {
357 | "branch": "master",
358 | "repoFolder": [
359 | { ".git": [ ] },
360 | { "planes_septiembre" : [ "desarrollo.txt" ] },
361 | { "planes_octubre" : [ "maquetado.txt" ] },
362 | "reuniones_del_mes.txt",
363 | "mi_plan.txt"
364 | ],
365 | "commits": [
366 | "20b5ccd - Agregar mi_plan.txt",
367 | "3852b4d - Agregar todos los archivos de texto"
368 | ]
369 | }
370 | },
371 | "13": {
372 | "orden": "13",
373 | "titulo": "Usando git push",
374 | "tituloCorto": "Git push",
375 | "tareas": [
376 | "Una vez asociado nuestro repositorio local solo tenemos que subir nuestros archivos locales a ese repositorio en línea, a esto se le llama hacer un push.",
377 | "Para hacerlo usamos el comando git push -u seguido del nombre del repositorio remoto a donde queremos hacer el push (origin) y luego el nombre de la rama del repositorio local donde están nuestros archivos. Por defecto, al inicializar un repositorio se crea una rama local llamada master, allí están nuestros documentos.",
378 | "¿Qué tal si lo intentas?"
379 | ],
380 | "comando": "git push -u origin master",
381 | "alert": "Did not use git push",
382 | "successMessages": [
383 | "Branch master set up to track remote branch"
384 | ],
385 | "repoStatus": {
386 | "branch": "master",
387 | "repoFolder": [
388 | { ".git": [ ] },
389 | { "planes_septiembre" : [ "desarrollo.txt" ] },
390 | { "planes_octubre" : [ "maquetado.txt" ] },
391 | "reuniones_del_mes.txt",
392 | "mi_plan.txt"
393 | ],
394 | "commits": [
395 | "20b5ccd - Agregar mi_plan.txt",
396 | "3852b4d - Agregar todos los archivos de texto"
397 | ]
398 | }
399 | },
400 | "14": {
401 | "orden": "14",
402 | "titulo": "Usando git pull",
403 | "tituloCorto": "Git pull",
404 | "tareas": [
405 | "Es bueno que siempre trabajes con la versión más actual de tu repositorio, es por ello que antes de hacer cualquier cosa siempre actualices tu repositorio local porque tal vez algún miembro de tu equipo ha realizado algún cambio importante",
406 | "Para actualizar nuestro repositorio local usamos git pull seguido del nombre del repositorio en línea de donde copiaremos los archivos (origin) y luego el nombre de la rama de nuestro repositorio local donde deseamos que se copien (master)."
407 | ],
408 | "comando": "git pull origin master",
409 | "alert": "Did not use git pull",
410 | "successMessages": [
411 | "Updating 3852b4d..3e70b0f",
412 | "Fast-forward",
413 | " resumen_mensual.txt | 1+",
414 | " 1 file changed, 1 insertion(+)",
415 | " create mode 100644 resumen_mensual.txt"
416 | ],
417 | "repoStatus": {
418 | "branch": "master",
419 | "repoFolder": [
420 | { ".git": [ ] },
421 | { "planes_septiembre" : [ "desarrollo.txt" ] },
422 | { "planes_octubre" : [ "maquetado.txt" ] },
423 | "reuniones_del_mes.txt",
424 | "mi_plan.txt"
425 | ],
426 | "commits": [
427 | "20b5ccd - Agregar mi_plan.txt",
428 | "3852b4d - Agregar todos los archivos de texto",
429 | "7d8d808 - Editar frecuencia de reuniones en mi_plan.txt"
430 | ]
431 | }
432 | },
433 | "15": {
434 | "orden": "15",
435 | "titulo": "Observando las ediciones con git diff",
436 | "tituloCorto": "Git diff",
437 | "tareas": [
438 | "¿Notas algo diferente en la carpeta de tu repositorio?",
439 | "Parece que un miembro de tu equipo ha editado nuestro archivo mi_plan.txt y ha hecho un push al repositorio en GitHub. Antes de comenzar a trabajar creo que mejor revisamos qué cambios realizó nuestro compañero.",
440 | "Para ello podemos usar el comando git diff HEAD donde HEAD es una referencia al commit más reciente."
441 | ],
442 | "comando": "git diff HEAD",
443 | "alert": "Did not use git diff",
444 | "successMessages": [
445 | "diff --git a/mi_plan.txt b/mi_plan.txt",
446 | "index 7d8d808..e725ef6 100644",
447 | "--- a/mi_plan.txt",
448 | "+++ b/mi_plan.txt",
449 | "@@ -1 +1 @@",
450 | "-Realizar reuniones mensuales",
451 | "+Realizar reuniones quincenales"
452 | ],
453 | "repoStatus": {
454 | "branch": "master",
455 | "repoFolder": [
456 | { ".git": [ ] },
457 | { "planes_septiembre" : [ "desarrollo.txt" ] },
458 | { "planes_octubre" : [ "maquetado.txt" ] },
459 | "reuniones_del_mes.txt",
460 | "mi_plan.txt"
461 | ],
462 | "commits": [
463 | "20b5ccd - Agregar mi_plan.txt",
464 | "3852b4d - Agregar todos los archivos de texto",
465 | "7d8d808 - Editar frecuencia de reuniones en mi_plan.txt"
466 | ]
467 | }
468 | },
469 | "16": {
470 | "orden": "16",
471 | "titulo": "Eliminando cambios",
472 | "tituloCorto": "Git checkout",
473 | "tareas": [
474 | "Bien, ya podemos ver las diferencias. Ahora, imagina que luego de unos minutos de trabajo has realizado un par de cambios en reuniones_del_mes.txt, pero resulta que has cometido un error. Podemos deshacer estos cambios con un comando de Git.",
475 | "Para ello, usamos el comando git checkout seguido del nombre del archivo al cual deseas eliminarle los cambios."
476 | ],
477 | "comando": "git checkout \"reuniones_del_mes.txt\"",
478 | "alert": "Did not use git checkout",
479 | "successMessages": [
480 | "Cambios eliminados"
481 | ],
482 | "repoStatus": {
483 | "branch": "master",
484 | "repoFolder": [
485 | { ".git": [ ] },
486 | { "planes_septiembre" : [ "desarrollo.txt" ] },
487 | { "planes_octubre" : [ "maquetado.txt" ] },
488 | "reuniones_del_mes.txt",
489 | "mi_plan.txt"
490 | ],
491 | "commits": [
492 | "20b5ccd - Agregar mi_plan.txt",
493 | "3852b4d - Agregar todos los archivos de texto",
494 | "7d8d808 - Editar frecuencia de reuniones en mi_plan.txt"
495 | ]
496 | }
497 | },
498 | "17": {
499 | "orden": "17",
500 | "titulo": "Trabajando con ramas",
501 | "tituloCorto": "Ramificación",
502 | "tareas": [
503 | "¿Recuerdas que dijimos que Git permitía a un equipo de trabajo tratar con un mismo código sin problemas? Bueno, esto es posible gracias a la ramificación del código.",
504 | "Git permite crear ramas o branches. Estas son copias de tu código en las que puedes trabajar sin afectar la versión original.",
505 | "¿Por qué no creamos una? Para ello usa el comando git branch seguido del nombre de la rama. Llamaremos a la nuestra mi_version."
506 | ],
507 | "comando": "git branch mi_version",
508 | "alert": "Did not use git branch",
509 | "successMessages": [
510 | "Rama creada"
511 | ],
512 | "repoStatus": {
513 | "branch": "master",
514 | "repoFolder": [
515 | { ".git": [ ] },
516 | { "planes_septiembre" : [ "desarrollo.txt" ] },
517 | { "planes_octubre" : [ "maquetado.txt" ] },
518 | "reuniones_del_mes.txt",
519 | "mi_plan.txt"
520 | ],
521 | "commits": [
522 | "20b5ccd - Agregar mi_plan.txt",
523 | "3852b4d - Agregar todos los archivos de texto",
524 | "7d8d808 - Editar frecuencia de reuniones en mi_plan.txt"
525 | ]
526 | }
527 | },
528 | "18": {
529 | "orden": "18",
530 | "titulo": "Cambiando de ramas",
531 | "tituloCorto": "Ramificación #2",
532 | "tareas": [
533 | "Bien, hemos creado una nueva rama. Pero como puedes ver a tu derecha en la sección Root folder aún seguimos en la rama principal master. Si queremos trabajar con nuestra copia debemos cambiar de rama.",
534 | "Para hacerlo usamos el comando git checkout seguido del nombre de la rama."
535 | ],
536 | "comando": "git checkout mi_version",
537 | "alert": "Did not use git checkout",
538 | "successMessages": [
539 | "Switched to branch 'mi_version'"
540 | ],
541 | "repoStatus": {
542 | "branch": "master",
543 | "repoFolder": [
544 | { ".git": [ ] },
545 | { "planes_septiembre" : [ "desarrollo.txt" ] },
546 | { "planes_octubre" : [ "maquetado.txt" ] },
547 | "reuniones_del_mes.txt",
548 | "mi_plan.txt"
549 | ],
550 | "commits": [
551 | "20b5ccd - Agregar mi_plan.txt",
552 | "3852b4d - Agregar todos los archivos de texto",
553 | "7d8d808 - Editar frecuencia de reuniones en mi_plan.txt"
554 | ]
555 | }
556 | },
557 | "19": {
558 | "orden": "19",
559 | "titulo": "Realizando cambios en nuestra rama",
560 | "tituloCorto": "Ramificación #3",
561 | "tareas": [
562 | "Como podrás notar, ya estamos en nuestra rama. Ahora, ¿qué tal si organizamos un poco mejor nuestro proyecto? Hemos creado una carpeta llamada tareas y allí moveremos los archivos que están en planes_septiembre y planes_octubre.",
563 | "Hemos hecho esto por ti, como puedes ver en Root folder. Ahora, a veces es algo tedioso tener que agregar los archivos al Stage y luego hacer commit. Es por ello que Git nos permie agregar -a al comando git commit el cual se hará cargo de agregar todos los archivos editados al Stage e inmediatamente hacer commit.",
564 | "Bien, ejecuta el comando correspodiente y agrega el mensaje: Reorganizar el proyecto."
565 | ],
566 | "comando": "git commit -a -m \"Reorganizar el proyecto\"",
567 | "alert": "Did not use git commit",
568 | "successMessages": [
569 | "[mi_version a5cd2f1] Reorganizar proyecto",
570 | " 2 files changed, 0 insertions(+), 0 deletions(-)",
571 | " rename {1 => tareas}/desarrollo.txt",
572 | " rename {1 => tareas}/maquetado.txt"
573 | ],
574 | "repoStatus": {
575 | "branch": "mi_version",
576 | "repoFolder": [
577 | { ".git": [ ] },
578 | { "tareas" :
579 | [
580 | "desarrollo.txt",
581 | "maquetado.txt"
582 | ]
583 | },
584 | "reuniones_del_mes.txt",
585 | "mi_plan.txt"
586 | ],
587 | "commits": [
588 | "20b5ccd - Agregar mi_plan.txt",
589 | "3852b4d - Agregar todos los archivos de texto",
590 | "7d8d808 - Editar frecuencia de reuniones en mi_plan.txt",
591 | "a5cd2f1 - Reorganizar el proyecto"
592 | ]
593 | }
594 | },
595 | "20": {
596 | "orden": "20",
597 | "titulo": "Regresando a la rama principal",
598 | "tituloCorto": "Ramificación #4",
599 | "tareas": [
600 | "Ahora que ya hemos hecho un commit de nuestros cambios, debemos unirlo a la rama principal para que todo nuestro equipo trabaje con la misma estructura. Para ello primero debemos regresar a la rama principal usando el comando git checkout master."
601 | ],
602 | "comando": "git checkout master",
603 | "alert": "Did not use git checkout",
604 | "successMessages": [
605 | "Switched to branch 'master'"
606 | ],
607 | "repoStatus": {
608 | "branch": "mi_version",
609 | "repoFolder": [
610 | { ".git": [ ] },
611 | { "tareas" :
612 | [
613 | "desarrollo.txt",
614 | "maquetado.txt"
615 | ]
616 | },
617 | "reuniones_del_mes.txt",
618 | "mi_plan.txt"
619 | ],
620 | "commits": [
621 | "20b5ccd - Agregar mi_plan.txt",
622 | "3852b4d - Agregar todos los archivos de texto",
623 | "7d8d808 - Editar frecuencia de reuniones en mi_plan.txt"
624 | ]
625 | }
626 | },
627 | "21": {
628 | "orden": "21",
629 | "titulo": "Uniendo nuestros cambios a Master",
630 | "tituloCorto": "Git merge",
631 | "tareas": [
632 | "Como podrás ver la rama master no ha sido alternada y todavía tiene la versión anterior de la estructura de nuestras carpetas. ¿Qué tal si aplicamos los cambios que hicimos en nuestra versión a la rama principal?",
633 | "Para ello usa el comando git merge. Esto lo que hará será tomar los cambios realizados en mi_version y unirlos a master."
634 | ],
635 | "comando": "git merge mi_version",
636 | "alert": "Did not use git merge",
637 | "successMessages": [
638 | "Updating 7d8d808..ec6888b",
639 | "Fast-forward",
640 | " {1 => tareas}/desarrollo.txt | 0",
641 | " {1 => tareas}/maquetado.txt | 0",
642 | " 2 files changed, 0 insertions(+), 0 deletions(-)",
643 | " rename {1 => tareas}/desarrollo.txt",
644 | " rename {1 => tareas}/maquetado.txt"
645 | ],
646 | "repoStatus": {
647 | "branch": "master",
648 | "repoFolder": [
649 | { ".git": [ ] },
650 | { "planes_septiembre" : [ "desarrollo.txt" ] },
651 | { "planes_octubre" : [ "maquetado.txt" ] },
652 | "reuniones_del_mes.txt",
653 | "mi_plan.txt"
654 | ],
655 | "commits": [
656 | "20b5ccd - Agregar mi_plan.txt",
657 | "3852b4d - Agregar todos los archivos de texto",
658 | "7d8d808 - Editar frecuencia de reuniones en mi_plan.txt"
659 | ]
660 | }
661 | },
662 | "22": {
663 | "orden": "22",
664 | "titulo": "Eliminando ramas en desuso",
665 | "tituloCorto": "Eliminan ramas",
666 | "tareas": [
667 | "Ya que hemos unido nuestros cambios a la rama principal y ya no usaremos más mi_vesion, ¿por qué no eliminamos esa rama?",
668 | "Siempre es bueno eliminar ramas en desuso, ya que a lo largo de un proyecto pueden generarse muchas ramas y debemos evitar que nuestros compañeros se confundan al usar ramas desactualizadas.",
669 | "Para ello usamos el comando git branch -d seguido del nombre de la rama a eliminar: mi_version."
670 | ],
671 | "comando": "git branch -d mi_version",
672 | "alert": "Did not use git branch",
673 | "successMessages": [
674 | "Deleted branch mi_version (was a5cd2f1)."
675 | ],
676 | "repoStatus": {
677 | "branch": "master",
678 | "repoFolder": [
679 | { ".git": [ ] },
680 | { "tareas" :
681 | [
682 | "desarrollo.txt",
683 | "maquetado.txt"
684 | ]
685 | },
686 | "reuniones_del_mes.txt",
687 | "mi_plan.txt"
688 | ],
689 | "commits": [
690 | "20b5ccd - Agregar mi_plan.txt",
691 | "3852b4d - Agregar todos los archivos de texto",
692 | "7d8d808 - Editar frecuencia de reuniones en mi_plan.txt",
693 | "a5cd2f1 - Reorganizar el proyecto"
694 | ]
695 | }
696 | },
697 | "23": {
698 | "orden": "23",
699 | "titulo": "Compartiendo nuestro proyecto",
700 | "tituloCorto": "Git push #2",
701 | "tareas": [
702 | "Ya habiendo realizado todos los cambios necesarios es hora de que nuestro equipo comience a trabajar con nuestro repositorio.",
703 | "Así que subamoslo a GitHub para ponernos en marcha."
704 | ],
705 | "comando": "git push",
706 | "alert": "Did not use git push",
707 | "successMessages": [
708 | "To https://github.com/4geeksAcademy/project.git",
709 | "a5cd2f1..a629e2a master -> master"
710 | ],
711 | "repoStatus": {
712 | "branch": "master",
713 | "repoFolder": [
714 | { ".git": [ ] },
715 | { "tareas" :
716 | [
717 | "desarrollo.txt",
718 | "maquetado.txt"
719 | ]
720 | },
721 | "reuniones_del_mes.txt",
722 | "mi_plan.txt"
723 | ],
724 | "commits": [
725 | "20b5ccd - Agregar mi_plan.txt",
726 | "3852b4d - Agregar todos los archivos de texto",
727 | "7d8d808 - Editar frecuencia de reuniones en mi_plan.txt",
728 | "a5cd2f1 - Reorganizar el proyecto"
729 | ]
730 | }
731 | }
732 | },
733 | "en": {
734 | "1": {
735 | "orden": "1",
736 | "titulo": "Want to learn some Git?",
737 | "tituloCorto": "Learn Git",
738 | "tareas": [
739 | "Git is a distributed version control system that allows people and teams to collaborate, editing the same document or code at the same time, without conflicts,",
740 | "In the terminal displayed on the lower part of your screen, we have created a repository, a container of files. To initialize the repository, type the following command: git init."
741 | ],
742 | "comando": "git init",
743 | "alert": "Did not create a Git repo",
744 | "successMessages": [
745 | "Initialized empty Git repository in /.git/"
746 | ],
747 | "repoStatus": {}
748 | },
749 | "2": {
750 | "orden": "2",
751 | "titulo": "Checking your repo",
752 | "tituloCorto": "Repo status",
753 | "tareas": [
754 | "Well done. You have created your first repository. The git init command adds a hidden subfolder within the existing directory named /.git/. If you create a git repository in your computer, this folder will be hidden. This hidden folder contains subfolders and files that reference every change you did in your repository after initializing it.",
755 | "Now let's check the current status of our repository with the command: git status."
756 | ],
757 | "comando": "git status",
758 | "alert": "Did not use git status",
759 | "successMessages": [
760 | "# On branch master",
761 | "#",
762 | "# Initial commit",
763 | "#",
764 | "nothing to commit",
765 | "(create/copy files and use \"git add\" to track)"
766 | ],
767 | "repoStatus": {
768 | "branch": "master",
769 | "repoFolder": [
770 | { ".git": [ ] },
771 | "my_plan.txt"
772 | ]
773 | }
774 | },
775 | "3": {
776 | "orden": "3",
777 | "titulo": "Start working on the new repo",
778 | "tituloCorto": "Getting started",
779 | "tareas": [
780 | "If at any point during this tutorial you feel your terminal is too cluttered with text, you can clear its contents with the clear command.",
781 | "Let's continue. Let's imagine we added a new file called my_plan.txt in the repository.",
782 | "Use again the command git status now. You will notice that the status of the repository has changed ."
783 | ],
784 | "comando": "git status",
785 | "alert": "Did not use git status",
786 | "successMessages": [
787 | "# On branch master",
788 | "#",
789 | "# Initial commit",
790 | "#",
791 | "# Untracked files:",
792 | "# (use \"git add ...\" to include files)",
793 | "#",
794 | "# my_plan.txt",
795 | "nothing added to commit",
796 | "but untracked files present",
797 | "(use 'git add' to track)"
798 | ],
799 | "repoStatus": {
800 | "branch": "master",
801 | "repoFolder": [
802 | { ".git": [ ] },
803 | "my_plan.txt"
804 | ]
805 | }
806 | },
807 | "4": {
808 | "orden": "4",
809 | "titulo": "Adding and updating files",
810 | "tituloCorto": "Adding and updating files",
811 | "tareas": [
812 | "The output of the git status command is telling us that my_plan.txt is untracked",
813 | "This means that the new file has not yet been added to the Git tracking process",
814 | "To have Git to track this file, type the command git add [file name]. This process is called Staging, or moving files to the Staging index tree, meaning our changes are ready to be committed"
815 | ],
816 | "comando": "git add my_plan.txt",
817 | "alert": "Did not add my_plan.txt",
818 | "successMessages": [
819 | "Well done! my_plan.txt has been Staged"
820 | ],
821 | "repoStatus": {
822 | "branch": "master",
823 | "repoFolder": [
824 | { ".git": [ ] },
825 | "my_plan.txt"
826 | ],
827 | "staged": [
828 | "my_plan.txt"
829 | ]
830 | }
831 | },
832 | "5": {
833 | "orden": "5",
834 | "titulo": "Reviewing changes",
835 | "tituloCorto": "Reviewing changes",
836 | "tareas": [
837 | "Excellent! Now that we made Git aware of the changes in our file, let's check again the status with the git status command to make sure everything is good."
838 | ],
839 | "comando": "git status",
840 | "alert": "Did not use git status",
841 | "successMessages": [
842 | "# On branch master",
843 | "#",
844 | "# Initial commit",
845 | "#",
846 | "# Changes to be committed:",
847 | "# (use \"git rm --cached ...\" to unstage)",
848 | "#",
849 | "# new file: my_plan.txt",
850 | "#"
851 | ],
852 | "repoStatus": {
853 | "branch": "master",
854 | "repoFolder": [
855 | { ".git": [ ] },
856 | "my_plan.txt"
857 | ],
858 | "staged": [
859 | "my_plan.txt"
860 | ]
861 | }
862 | },
863 | "6": {
864 | "orden": "6",
865 | "titulo": "Committing your staged changes",
866 | "tituloCorto": "Committing changes",
867 | "tareas": [
868 | "Now that our changes are Staged, we are ready to commit the changes.",
869 | "Commit means simply to that our Staged changes are ready to be added to our repository. If you wish, you can add or remove files and add them to the Staging index them as necessary before committing the changes",
870 | "To save the changes in our repository, use the command git commit -m followed by a commit message that briefly states what exactly happened in between the last version and this. In this case, we added a new archive in an empty repository, so the commit message will be simple: Added my_plan.txt (enclosed in double quotes)."
871 | ],
872 | "comando": "git commit -m \"Added my_plan.txt\"",
873 | "alert": "Did not use git commit",
874 | "successMessages": [
875 | "[master (root-commit) 20b5ccd] Added my_plan.txt",
876 | "1 file changed, 1 insertion(+)",
877 | "create mode 100644 my_plan.txt",
878 | " "
879 | ],
880 | "repoStatus": {
881 | "branch": "master",
882 | "repoFolder": [
883 | { ".git": [ ] },
884 | "my_plan.txt"
885 | ],
886 | "commits": [
887 | "20b5ccd - Added my_plan.txt"
888 | ]
889 | }
890 | },
891 | "7": {
892 | "orden": "7",
893 | "titulo": "Adding multiple files",
894 | "tituloCorto": "Adding multiple files",
895 | "tareas": [
896 | "Our repository already has one commit. But what if you have been working all day in this project, and now you have a few new text files to commit? Adding them one by one with the git add command is quite tedious, right? No worries, Git has a better method to add multiple files.",
897 | "Type the command git add \"*.txt\", in order to add all the text tiles that have been added or edited in our repository."
898 | ],
899 | "comando": "git add \"*.txt\"",
900 | "alert": "Did not use git add",
901 | "successMessages": [
902 | ""
903 | ],
904 | "repoStatus": {
905 | "branch": "master",
906 | "repoFolder": [
907 | { ".git": [ ] },
908 | { "september_plans" : [ "development.txt" ] },
909 | { "october_plans" : [ "mockup.txt" ] },
910 | "monthly_meetings.txt",
911 | "my_plan.txt"
912 | ],
913 | "staged": [
914 | { "september_plans" : [ "development.txt" ] },
915 | { "october_plans" : [ "mockup.txt" ] },
916 | "monthly_meetings.txt"
917 | ],
918 | "commits": [
919 | "20b5ccd - Added my_plan.txt"
920 | ]
921 | }
922 | },
923 | "8": {
924 | "orden": "8",
925 | "titulo": "Revert to Stage",
926 | "tituloCorto": "Git reset",
927 | "tareas": [
928 | "We know that the git add command sends edited files to the Staging index. The command git reset does the the exact opposite: It reverts to the previous state of Stage.",
929 | "This command accepts the same arguments as git add.",
930 | "Let's try to reset the last files we added to Stage."
931 | ],
932 | "comando": "git reset",
933 | "alert": "Did not use git reset",
934 | "successMessages": [
935 | "Text files were removed from Stage"
936 | ],
937 | "repoStatus": {
938 | "branch": "master",
939 | "repoFolder": [
940 | { ".git": [ ] },
941 | { "september_plans" : [ "development.txt" ] },
942 | { "october_plans" : [ "mockup.txt" ] },
943 | "monthly_meetings.txt",
944 | "my_plan.txt"
945 | ],
946 | "commits": [
947 | "20b5ccd - Added my_plan.txt"
948 | ]
949 | }
950 | },
951 | "9": {
952 | "orden": "9",
953 | "titulo": "Adding files again",
954 | "tituloCorto": "Git add #2",
955 | "tareas": [
956 | "As you see on the right panel, our files are not anymore on the Staging index.",
957 | "Let's add them again."
958 | ],
959 | "comando": "git add \"*.txt\"",
960 | "alert": "Did not use git add",
961 | "successMessages": [
962 | "Added files"
963 | ],
964 | "repoStatus": {
965 | "branch": "master",
966 | "repoFolder": [
967 | { ".git": [ ] },
968 | { "september_plans" : [ "development.txt" ] },
969 | { "october_plans" : [ "mockup.txt" ] },
970 | "monthly_meetings.txt",
971 | "my_plan.txt"
972 | ],
973 | "staged": [
974 | { "september_plans" : [ "development.txt" ] },
975 | { "october_plans" : [ "mockup.txt" ] },
976 | "monthly_meetings.txt"
977 | ],
978 | "commits": [
979 | "20b5ccd - Added my_plan.txt"
980 | ]
981 | }
982 | },
983 | "10": {
984 | "orden": "10",
985 | "titulo": "Committing newly staged changes",
986 | "tituloCorto": "Committing files #2",
987 | "tareas": [
988 | "Let's commit our newly staged changes.",
989 | "How about adding a more descriptive commit message, such as Added all text files?"
990 | ],
991 | "comando": "git commit -m \"Added all text files\"",
992 | "alert": "Did not use git commit",
993 | "successMessages": [
994 | "[master (root-commit) 3852b4d]",
995 | "'Added all text files'",
996 | "3 file changed, 3 insertion(+)",
997 | "create mode 100644 development.txt",
998 | "create mode 100644 mockup.txt",
999 | "create mode 100644 monthly_meetings.txt",
1000 | " "
1001 | ],
1002 | "repoStatus": {
1003 | "branch": "master",
1004 | "repoFolder": [
1005 | { ".git": [ ] },
1006 | { "september_plans" : [ "development.txt" ] },
1007 | { "october_plans" : [ "mockup.txt" ] },
1008 | "monthly_meetings.txt",
1009 | "my_plan.txt"
1010 | ],
1011 | "commits": [
1012 | "20b5ccd - Added my_plan.txt",
1013 | "3852b4d - Added all text files"
1014 | ]
1015 | }
1016 | },
1017 | "11": {
1018 | "orden": "11",
1019 | "titulo": "Reviewing history of changes with git log",
1020 | "tituloCorto": "Using git log",
1021 | "tareas": [
1022 | "How about it? We have already done two commits.",
1023 | "Git has a command that allows us to review a log of all of our commits in chronological order. Type git log on the terminal:"
1024 | ],
1025 | "comando": "git log",
1026 | "alert": "Did not use git log",
1027 | "successMessages": [
1028 | "commit: 3852b4db1634463d0bb4d267edb7b3f9cd02ace1",
1029 | "Author: 4Geeks Student ",
1030 | "Date: Fri Sep 19 18:30:00 2017 -0400",
1031 | " Added my_plan.txt",
1032 | " ",
1033 | "commit: b652edfd888cd3d5e7fcb857d0dabc5a0fcb5e28",
1034 | "Author: 4Geeks Student ",
1035 | "Date: Thu Sep 18 18:00:32 2017 -0400",
1036 | " Added all text files"
1037 | ],
1038 | "repoStatus": {
1039 | "branch": "master",
1040 | "repoFolder": [
1041 | { ".git": [ ] },
1042 | { "september_plans" : [ "development.txt" ] },
1043 | { "october_plans" : [ "mockup.txt" ] },
1044 | "monthly_meetings.txt",
1045 | "my_plan.txt"
1046 | ],
1047 | "commits": [
1048 | "20b5ccd - Added my_plan.txt",
1049 | "3852b4d - Added all text files"
1050 | ]
1051 | }
1052 | },
1053 | "12": {
1054 | "orden": "12",
1055 | "titulo": "Managing remote repositories",
1056 | "tituloCorto": "Git remote",
1057 | "tareas": [
1058 | "Great, we have now learned the most basic Git commands. Let's put our knowledge in practice. Imagine that you need other people to access your repository. To do this, you have to upload the repository to a platform such as GitHub a service that hosts public and private repositories.",
1059 | "Once our Github repository is created, we have to associate it with our local repository. For this, we will use the git remote add command, followed by the name and the URL of the remote repository. Usually, the main remote repository is named origin. The URL of the remote repository should be https://github.com/4geeksAcademy/project.git (double quotes are not needed)"
1060 | ],
1061 | "comando": "git remote add origin https://github.com/4geeksAcademy/project.git",
1062 | "alert": "Did not use git remote add",
1063 | "successMessages": [
1064 | "Successfully added repository"
1065 | ],
1066 | "repoStatus": {
1067 | "branch": "master",
1068 | "repoFolder": [
1069 | { ".git": [ ] },
1070 | { "september_plans" : [ "development.txt" ] },
1071 | { "october_plans" : [ "mockup.txt" ] },
1072 | "monthly_meetings.txt",
1073 | "my_plan.txt"
1074 | ],
1075 | "commits": [
1076 | "20b5ccd - Added my_plan.txt",
1077 | "3852b4d - Added all text files"
1078 | ]
1079 | }
1080 | },
1081 | "13": {
1082 | "orden": "13",
1083 | "titulo": "Using git push",
1084 | "tituloCorto": "Git push",
1085 | "tareas": [
1086 | "After associating our local repository with the remote, we will upload our files to the remote, or push our local repository.",
1087 | "Type git push -u followed by the name of the remote repository (origin) and then the name of the local branch we want to push. When we initialize a repository, a local branch called master is created automatically, and contains our files.",
1088 | "Let's try it?"
1089 | ],
1090 | "comando": "git push -u origin master",
1091 | "alert": "Did not use git push",
1092 | "successMessages": [
1093 | "Branch master set up to track remote branch"
1094 | ],
1095 | "repoStatus": {
1096 | "branch": "master",
1097 | "repoFolder": [
1098 | { ".git": [ ] },
1099 | { "september_plans" : [ "development.txt" ] },
1100 | { "october_plans" : [ "mockup.txt" ] },
1101 | "monthly_meetings.txt",
1102 | "my_plan.txt"
1103 | ],
1104 | "commits": [
1105 | "20b5ccd - Added my_plan.txt",
1106 | "3852b4d - Added all text files"
1107 | ]
1108 | }
1109 | },
1110 | "14": {
1111 | "orden": "14",
1112 | "titulo": "Using git pull",
1113 | "tituloCorto": "Git pull",
1114 | "tareas": [
1115 | "It is a good practice to always work with the most recent version of your repository, to make sure that you are not ignoring possible important changes by a team member. This is easily done with Git, as we can update our local repository to match the content of the remote repository.",
1116 | "To update your local repository, type git pull, followed by the name of the remote repository(origin) and the name of the local branch where that will get updated (master)."
1117 | ],
1118 | "comando": "git pull origin master",
1119 | "alert": "Did not use git pull",
1120 | "successMessages": [
1121 | "Updating 3852b4d..3e70b0f",
1122 | "Fast-forward",
1123 | " monthly_summary.txt | 1+",
1124 | " 1 file changed, 1 insertion(+)",
1125 | " create mode 100644 monthly_summary.txt"
1126 | ],
1127 | "repoStatus": {
1128 | "branch": "master",
1129 | "repoFolder": [
1130 | { ".git": [ ] },
1131 | { "september_plans" : [ "development.txt" ] },
1132 | { "october_plans" : [ "mockup.txt" ] },
1133 | "monthly_meetings.txt",
1134 | "my_plan.txt"
1135 | ],
1136 | "commits": [
1137 | "20b5ccd - Added my_plan.txt",
1138 | "3852b4d - Added all text files",
1139 | "7d8d808 - Edited meetings frequency in my_plan.txt"
1140 | ]
1141 | }
1142 | },
1143 | "15": {
1144 | "orden": "15",
1145 | "titulo": "Comparing different versions with git diff",
1146 | "tituloCorto": "Git diff",
1147 | "tareas": [
1148 | "Did you notice something different in your repository?",
1149 | "Looks like a team member has edited our my_plan.txt file and pushed the changes to the GitHub repository. Let's review the edits from our teammate before starting work.",
1150 | "Let's use the command git diff HEAD, where HEAD refers to the most recent commit."
1151 | ],
1152 | "comando": "git diff HEAD",
1153 | "alert": "Did not use git diff",
1154 | "successMessages": [
1155 | "diff --git a/my_plan.txt b/my_plan.txt",
1156 | "index 7d8d808..e725ef6 100644",
1157 | "--- a/my_plan.txt",
1158 | "+++ b/my_plan.txt",
1159 | "@@ -1 +1 @@",
1160 | "-Monthly meetings",
1161 | "+Meetings twice a month"
1162 | ],
1163 | "repoStatus": {
1164 | "branch": "master",
1165 | "repoFolder": [
1166 | { ".git": [ ] },
1167 | { "september_plans" : [ "development.txt" ] },
1168 | { "october_plans" : [ "mockup.txt" ] },
1169 | "monthly_meetings.txt",
1170 | "my_plan.txt"
1171 | ],
1172 | "commits": [
1173 | "20b5ccd - Added my_plan.txt",
1174 | "3852b4d - Added all text files",
1175 | "7d8d808 - Edited meetings frequency in my_plan.txt"
1176 | ]
1177 | }
1178 | },
1179 | "16": {
1180 | "orden": "16",
1181 | "titulo": "Reverting changes",
1182 | "tituloCorto": "Git checkout",
1183 | "tareas": [
1184 | "So we now know how to see review changes. Now, imagine that, after working for a few minutes updating the content of monthly_meetings.txt, you realize that you made a mistake. Not to worry; we can revert these changes with a Git command.",
1185 | "Type git checkout, followed by the name of the file that you need to revert your changes to."
1186 | ],
1187 | "comando": "git checkout \"monthly_meetings.txt\"",
1188 | "alert": "Did not use git checkout",
1189 | "successMessages": [
1190 | "Reverted changes"
1191 | ],
1192 | "repoStatus": {
1193 | "branch": "master",
1194 | "repoFolder": [
1195 | { ".git": [ ] },
1196 | { "september_plans" : [ "development.txt" ] },
1197 | { "october_plans" : [ "mockup.txt" ] },
1198 | "monthly_meetings.txt",
1199 | "my_plan.txt"
1200 | ],
1201 | "commits": [
1202 | "20b5ccd - Added my_plan.txt",
1203 | "3852b4d - Added all text files",
1204 | "7d8d808 - Edited meetings frequency in my_plan.txt"
1205 | ]
1206 | }
1207 | },
1208 | "17": {
1209 | "orden": "17",
1210 | "titulo": "Working with branches",
1211 | "tituloCorto": "Branching",
1212 | "tareas": [
1213 | "Remember we said that Git allows a work team to work on the same code simultaneously without conflicts? This is made possible with the Git branching model.",
1214 | "Git allows the creation of branches. Branches. Branches are complete copies of the code that can be used to work on, independently of the original version.",
1215 | "How about creating a branch? Type the command git branch, followed by the branch names. Let's name our branch my_version."
1216 | ],
1217 | "comando": "git branch my_version",
1218 | "alert": "Did not use git branch",
1219 | "successMessages": [
1220 | "Created branch"
1221 | ],
1222 | "repoStatus": {
1223 | "branch": "master",
1224 | "repoFolder": [
1225 | { ".git": [ ] },
1226 | { "september_plans" : [ "development.txt" ] },
1227 | { "october_plans" : [ "mockup.txt" ] },
1228 | "monthly_meetings.txt",
1229 | "my_plan.txt"
1230 | ],
1231 | "commits": [
1232 | "20b5ccd - Added my_plan.txt",
1233 | "3852b4d - Added all text files",
1234 | "7d8d808 - Edited meetings frequency in my_plan.txt"
1235 | ]
1236 | }
1237 | },
1238 | "18": {
1239 | "orden": "18",
1240 | "titulo": "Switching branches",
1241 | "tituloCorto": "Branching #2",
1242 | "tareas": [
1243 | "We have created a new branch. As you can see at the right panel, in the Root folder section, we are still working on the main, or master branch. To use our newly created branch, we have to switch to it.",
1244 | "Type git checkout, followed by the branch name"
1245 | ],
1246 | "comando": "git checkout my_version",
1247 | "alert": "Did not use git checkout",
1248 | "successMessages": [
1249 | "Switched to branch 'my_version'"
1250 | ],
1251 | "repoStatus": {
1252 | "branch": "master",
1253 | "repoFolder": [
1254 | { ".git": [ ] },
1255 | { "september_plans" : [ "development.txt" ] },
1256 | { "october_plans" : [ "mockup.txt" ] },
1257 | "monthly_meetings.txt",
1258 | "my_plan.txt"
1259 | ],
1260 | "commits": [
1261 | "20b5ccd - Added my_plan.txt",
1262 | "3852b4d - Added all text files",
1263 | "7d8d808 - Edited meetings frequency in my_plan.txt"
1264 | ]
1265 | }
1266 | },
1267 | "19": {
1268 | "orden": "19",
1269 | "titulo": "Committing changes to our branch",
1270 | "tituloCorto": "Branching #3",
1271 | "tareas": [
1272 | "As you can see, now we are working in our own branch. How about improving the structure of our project? We have created a folder named tasks, where we can move the files that are currently located in september_plans and october_plans.",
1273 | "As you can see on the Root folder section, we have already done this. Now, instead of adding the files to the Stage and then committing them, Git allows us to use the -a argument for the git commit command, which will add all the changed files to Stage and then commit the changes.",
1274 | "Commit the changes using the -a option and the message: Reorganized project."
1275 | ],
1276 | "comando": "git commit -a -m \"Reorganized project\"",
1277 | "alert": "Did not use git commit",
1278 | "successMessages": [
1279 | "[my_version a5cd2f1] Reorganized project",
1280 | " 2 files changed, 0 insertions(+), 0 deletions(-)",
1281 | " rename {1 => tasks}/development.txt",
1282 | " rename {1 => tasks}/mockup.txt"
1283 | ],
1284 | "repoStatus": {
1285 | "branch": "my_version",
1286 | "repoFolder": [
1287 | { ".git": [ ] },
1288 | { "tareas" :
1289 | [
1290 | "development.txt",
1291 | "mockup.txt"
1292 | ]
1293 | },
1294 | "monthly_meetings.txt",
1295 | "my_plan.txt"
1296 | ],
1297 | "commits": [
1298 | "20b5ccd - Added my_plan.txt",
1299 | "3852b4d - Added all text files",
1300 | "7d8d808 - Edited meetings frequency in my_plan.txt",
1301 | "a5cd2f1 - Reorganizar el proyecto"
1302 | ]
1303 | }
1304 | },
1305 | "20": {
1306 | "orden": "20",
1307 | "titulo": "Switching to master branch",
1308 | "tituloCorto": "Branching #4",
1309 | "tareas": [
1310 | "After committing our changes to our branch, we should merge it with the main branch, so that the rest of our team all have the same project structure. Let's switch to the main branch with the command git checkout master."
1311 | ],
1312 | "comando": "git checkout master",
1313 | "alert": "Did not use git checkout",
1314 | "successMessages": [
1315 | "Switched to branch 'master'"
1316 | ],
1317 | "repoStatus": {
1318 | "branch": "my_version",
1319 | "repoFolder": [
1320 | { ".git": [ ] },
1321 | { "tareas" :
1322 | [
1323 | "development.txt",
1324 | "mockup.txt"
1325 | ]
1326 | },
1327 | "monthly_meetings.txt",
1328 | "my_plan.txt"
1329 | ],
1330 | "commits": [
1331 | "20b5ccd - Added my_plan.txt",
1332 | "3852b4d - Added all text files",
1333 | "7d8d808 - Edited meetings frequency in my_plan.txt"
1334 | ]
1335 | }
1336 | },
1337 | "21": {
1338 | "orden": "21",
1339 | "titulo": "Merging changes to the Master branch",
1340 | "tituloCorto": "Git merge",
1341 | "tareas": [
1342 | "As you can see, the branch master has not been altered, so the changes we did in our own branch are not reflected to the master's branch folder structure. Let's apply our changes to the master branch!",
1343 | "Type git merge. With this command, the changes in the branch my_version will be merged with the master. branch"
1344 | ],
1345 | "comando": "git merge my_version",
1346 | "alert": "Did not use git merge",
1347 | "successMessages": [
1348 | "Updating 7d8d808..ec6888b",
1349 | "Fast-forward",
1350 | " {1 => tasks}/development.txt | 0",
1351 | " {1 => tasks}/mockup.txt | 0",
1352 | " 2 files changed, 0 insertions(+), 0 deletions(-)",
1353 | " rename {1 => tasks}/development.txt",
1354 | " rename {1 => tasks}/mockup.txt"
1355 | ],
1356 | "repoStatus": {
1357 | "branch": "master",
1358 | "repoFolder": [
1359 | { ".git": [ ] },
1360 | { "september_plans" : [ "development.txt" ] },
1361 | { "october_plans" : [ "mockup.txt" ] },
1362 | "monthly_meetings.txt",
1363 | "my_plan.txt"
1364 | ],
1365 | "commits": [
1366 | "20b5ccd - Added my_plan.txt",
1367 | "3852b4d - Added all text files",
1368 | "7d8d808 - Edited meetings frequency in my_plan.txt"
1369 | ]
1370 | }
1371 | },
1372 | "22": {
1373 | "orden": "22",
1374 | "titulo": "Deleting unused branches",
1375 | "tituloCorto": "Deleting branches",
1376 | "tareas": [
1377 | "We have merged our changes with the main branch, so we won't be using mi_vesion anymore. Let's remove this branch.",
1378 | "It is a good practice to delete unused branches, as, as our project increases, having many branches can be hard to maintain and many of the older branches can be left behind in updates.",
1379 | "Type git branch -d, followed by the name of the branch we want to delete: my_version."
1380 | ],
1381 | "comando": "git branch -d my_version",
1382 | "alert": "Did not use git branch",
1383 | "successMessages": [
1384 | "Deleted branch my_version (was a5cd2f1)."
1385 | ],
1386 | "repoStatus": {
1387 | "branch": "master",
1388 | "repoFolder": [
1389 | { ".git": [ ] },
1390 | { "tareas" :
1391 | [
1392 | "development.txt",
1393 | "mockup.txt"
1394 | ]
1395 | },
1396 | "monthly_meetings.txt",
1397 | "my_plan.txt"
1398 | ],
1399 | "commits": [
1400 | "20b5ccd - Added my_plan.txt",
1401 | "3852b4d - Added all text files",
1402 | "7d8d808 - Edited meetings frequency in my_plan.txt",
1403 | "a5cd2f1 - Reorganized project"
1404 | ]
1405 | }
1406 | },
1407 | "23": {
1408 | "orden": "23",
1409 | "titulo": "Sharing our project",
1410 | "tituloCorto": "Git push #2",
1411 | "tareas": [
1412 | "We have now made all the necessary changes to our project, so it is time to share the repository with our team so that we can all work in it.",
1413 | "Let's upload our repository to GitHub."
1414 | ],
1415 | "comando": "git push",
1416 | "alert": "Did not use git push",
1417 | "successMessages": [
1418 | "To https://github.com/4geeksAcademy/project.git",
1419 | "a5cd2f1..a629e2a master -> master"
1420 | ],
1421 | "repoStatus": {
1422 | "branch": "master",
1423 | "repoFolder": [
1424 | { ".git": [ ] },
1425 | { "tareas" :
1426 | [
1427 | "development.txt",
1428 | "mockup.txt"
1429 | ]
1430 | },
1431 | "monthly_meetings.txt",
1432 | "my_plan.txt"
1433 | ],
1434 | "commits": [
1435 | "20b5ccd - Added my_plan.txt",
1436 | "3852b4d - Added all text files",
1437 | "7d8d808 - Edited meetings frequency in my_plan.txt",
1438 | "a5cd2f1 - Reorganized project"
1439 | ]
1440 | }
1441 | }
1442 | }
1443 | }
1444 | }
1445 |
--------------------------------------------------------------------------------
/src/js/main.js:
--------------------------------------------------------------------------------
1 | import {} from 'sweetalert';
2 | import json from '../config/config.json';
3 |
4 | window.onload = () => loadPage();
5 | var lecciones = [];
6 |
7 | function loadPage() {
8 |
9 | // =================================================
10 | // GLOBAL VARIABLES
11 | // ==================================================
12 |
13 | function getQueryParam(param) {
14 | const urlParams = new URLSearchParams(window.location.search);
15 | return urlParams.get(param);
16 | }
17 |
18 | let lang = getQueryParam('lang') || document.querySelector('#lang').value || 'defaultLang';
19 | console.log(`Language selected: ${lang}`, json);
20 |
21 | lecciones = json.lecciones[lang];
22 | var config = json.config;
23 | var leccionActual = 1;
24 | var leccionesTotal = getObjLength(lecciones);
25 | var avanceActual = 0;
26 | var leccionPorcentaje = 100 / leccionesTotal;
27 |
28 | // User command history
29 | var commandHist = [];
30 | var commandPos = 1;
31 | // General areas
32 |
33 | var navbar = document.querySelector('nav');
34 | var consoleArea = document.querySelector('.console-area');
35 | var textarea = document.querySelector('#console-input');
36 | var areaTareas = document.querySelector('.tareas');
37 | var branchArea = document.querySelector('.branch');
38 | var repoFolderArea = document.querySelector('#repository .repo-status .repo-folder');
39 | var repoStagedArea = document.querySelector('#repository .repo-status .staged');
40 | var repoCommitsArea = document.querySelector('#repository .repo-status .commits');
41 |
42 | // Cambiar lenguaje
43 | const langSwitch = document.querySelector('#lang');
44 | langSwitch.addEventListener('change', () => {
45 |
46 | // avoid switching to invalid languages
47 | if(!['en', 'es', 'us'].includes(langSwitch.value)) return;
48 |
49 | lang = langSwitch.value;
50 | lecciones = json.lecciones[lang];
51 |
52 | // Actualizar la URL con el nuevo parámetro de lenguaje
53 | const newUrl = new URL(window.location);
54 | newUrl.searchParams.set('lang', lang);
55 | window.history.pushState({}, '', newUrl);
56 |
57 | consoleArea.appendChild(clearTerminal());
58 | addTextareaListener();
59 | actualizarInfoLeccion();
60 | // Actualizar Staged
61 | deleteAllChilds(repoStagedArea, 'h3');
62 | if (lecciones[leccionActual].repoStatus.staged != undefined) {
63 | let ul = document.createElement('ul');
64 | for (let i = 0; i < lecciones[leccionActual].repoStatus.staged.length; i++) {
65 | let li = createElementNode("li", lecciones[leccionActual].repoStatus.staged[i]);
66 | ul.appendChild(li).classList.add('staged');
67 | }
68 | repoStagedArea.appendChild(ul);
69 | }
70 | // Actualizar Repo Commits
71 | deleteAllChilds(repoCommitsArea, 'h3');
72 | if (lecciones[leccionActual] && lecciones[leccionActual].repoStatus.staged != undefined) {
73 | let ul = document.createElement('ul');
74 | for (let i = 0; i < lecciones[leccionActual].repoStatus.commits.length; i++) {
75 | let li = createElementNode("li", lecciones[leccionActual].repoStatus.commits[i]);
76 | ul.appendChild(li).classList.add('commit');
77 | }
78 | repoCommitsArea.appendChild(ul)
79 | } else {
80 | let ul = document.createElement('ul');
81 | let li = createElementNode("li", config.emptyCommitsAreaMessage);
82 | ul.appendChild(li).classList.add('commit');
83 | repoCommitsArea.appendChild(ul);
84 | }
85 | // Ayudar listener para el textarea
86 | textarea.focus();
87 | });
88 |
89 | // Inicializar con el lenguaje de la query string
90 | const initialLang = getQueryParam('lang') || 'en';
91 | langSwitch.value = initialLang;
92 | langSwitch.dispatchEvent(new Event('change'));
93 |
94 |
95 |
96 |
97 |
98 | // =================================================
99 | // COURSE TASKS FUNCTIONS
100 | // ==================================================
101 | // Updates every contentn area in the site
102 | function actualizarInfoLeccion() {
103 | if (!lecciones || !lecciones[leccionActual]) {
104 | console.error(`Lección ${leccionActual} no encontrada en el lenguaje ${lang}`);
105 | return;
106 | }
107 |
108 |
109 | // Actualizar titulo y orden
110 | let titulo = document.querySelector('#instrucciones .titulo');
111 | titulo.innerHTML = lecciones[leccionActual].titulo;
112 | let orden = document.querySelector('#instrucciones .orden');
113 | orden.innerHTML = lecciones[leccionActual].orden;
114 |
115 | // Actualizar comando en boton
116 | let button = document.querySelector('.comando');
117 | // Acortar el texto si es muy largo
118 | if (lecciones[leccionActual].comando.length > 50) {
119 | button.innerHTML = lecciones[leccionActual].comando.substring(0, 41) + "...";
120 | } else {
121 | button.innerHTML = lecciones[leccionActual].comando;
122 | }
123 |
124 | // Limpiar areaTareas
125 | deleteAllChilds(areaTareas);
126 | // Agregar nuevas Tareas
127 | for (var i = 0; i < lecciones[leccionActual].tareas.length; i++) {
128 | let parrafo = createElementNode("p" ,lecciones[leccionActual].tareas[i]);
129 | areaTareas.appendChild(parrafo);
130 | }
131 |
132 | // Actualizar Navbar
133 | deleteAllChilds(navbar, "a");
134 | navbar.appendChild(createNavbarLinks());
135 |
136 | // Actualizar Repo Folder
137 | deleteAllChilds(repoFolderArea, 'h3');
138 | if (lecciones[leccionActual].repoStatus.branch !== undefined) {
139 | if (lecciones[leccionActual].repoStatus.branch !== undefined) {
140 | branchArea.innerHTML = '(' + lecciones[leccionActual].repoStatus.branch + ')';
141 | }
142 | let folderStructure = createFolderStructure(lecciones[leccionActual].repoStatus.repoFolder);
143 | repoFolderArea.appendChild(folderStructure);
144 | } else {
145 | let ul = document.createElement('ul');
146 | let li = createElementNode("li", config.emptyFolderMessage);
147 | ul.appendChild(li).classList.add('info');
148 | repoFolderArea.appendChild(ul);
149 | }
150 | }
151 |
152 | // Evaluates command and shows a preddefined message from JSON
153 | function mostrarResultado(passOrFail) {
154 | // Mostrar resultado
155 | if (passOrFail == 'pass') {
156 | // PASSED
157 | // Actualizar barra de progreso
158 | avanceActual += leccionPorcentaje;
159 | document.querySelector('#myBar').style.width = avanceActual + "%";
160 | // Mensajes de exito
161 | for (var i = 0; i < lecciones[leccionActual].successMessages.length; i++) {
162 | let parrafo = createElementNode("p", lecciones[leccionActual].successMessages[i]);
163 | consoleArea.appendChild(parrafo);
164 | }
165 | let parrafo = createElementNode("p", config.success);
166 | parrafo.classList.add('success');
167 | consoleArea.appendChild(parrafo);
168 | // Actualizar Staged
169 | deleteAllChilds(repoStagedArea, 'h3');
170 | if (lecciones[leccionActual].repoStatus.staged !== undefined) {
171 | let folderStructure = createFolderStructure(lecciones[leccionActual].repoStatus.staged);
172 | repoStagedArea.appendChild(folderStructure);
173 | } else {
174 | let ul = document.createElement('ul');
175 | let li = createElementNode("li", config.emptyStageAreaMessage);
176 | ul.appendChild(li).classList.add('commit');
177 | repoStagedArea.appendChild(ul);
178 | }
179 |
180 | // Actualizar Repo Commits
181 | deleteAllChilds(repoCommitsArea, 'h3');
182 | if (lecciones[leccionActual].repoStatus.commits !== undefined) {
183 | let ul = document.createElement('ul');
184 | for (let i = 0; i < lecciones[leccionActual].repoStatus.commits.length; i++) {
185 | let li = createElementNode("li", lecciones[leccionActual].repoStatus.commits[i]);
186 | ul.appendChild(li).classList.add('commit');
187 | }
188 | repoCommitsArea.appendChild(ul);
189 | } else {
190 | let ul = document.createElement('ul');
191 | let li = createElementNode("li", config.emptyCommitsAreaMessage);
192 | ul.appendChild(li).classList.add('commit');
193 | repoCommitsArea.appendChild(ul);
194 | }
195 | // Siguiente leccion
196 | leccionActual++;
197 | } else {
198 | // FAILED
199 | let userCommand = textarea.value;
200 | let splitCommand = userCommand.match(/(git)\s(\w+)/g) !== null ? userCommand.match(/(git)\s(\w+)/g)[0] : undefined;
201 | let comando = lecciones[leccionActual].comando;
202 | if (splitCommand != undefined && comando.match(/(git)\s(\w+)/g)[0] == splitCommand) {
203 | let parrafo = createElementNode("p", "Used " + splitCommand);
204 | parrafo.classList.add('blue');
205 | consoleArea.appendChild(parrafo);
206 | parrafo = createElementNode("p", "Check your arguments");
207 | consoleArea.appendChild(parrafo);
208 | } else if (RegExp("(git)", "g").test(textarea.value.trim())) {
209 | for (var i = 0; i < config.errorMessages.length; i++) {
210 | let parrafo = createElementNode("p", config.errorMessages[i]);
211 | consoleArea.appendChild(parrafo);
212 | }
213 | // Red error message
214 | let parrafo = createElementNode("p", lecciones[leccionActual].alert);
215 | parrafo.classList.add('error');
216 | consoleArea.appendChild(parrafo);
217 | } else {
218 | let comandError = createElementNode("p", textarea.value + ": " + config.errorComando);
219 | comandError.style.marginTop
220 | consoleArea.appendChild(comandError);
221 | // Red error message
222 | let parrafo = createElementNode("p", lecciones[leccionActual].alert);
223 | parrafo.classList.add('error');
224 | consoleArea.appendChild(parrafo);
225 | }
226 |
227 | }
228 | }
229 | // Changes line and shows result every time the users presses Enter in console area
230 | function cambiarLineaActual(passOrFail) {
231 | let lineaActual = document.querySelector('.current-line');
232 | let div = document.createElement('div');
233 | div.classList.add('line');
234 | let parrafo = createElementNode("p", textarea.value);
235 | parrafo.style.marginTop = "15px";
236 | parrafo.style.marginBottom = "15px";
237 |
238 | let img = document.createElement('img');
239 | img.classList.add('line-marker');
240 | img.setAttribute('src', './img/logo-blue.png');
241 |
242 | consoleArea.removeChild(lineaActual);
243 | div.appendChild(img);
244 | div.appendChild(parrafo);
245 | consoleArea.appendChild(div);
246 | consoleArea.classList.remove('current-line');
247 |
248 | setTimeout(function() {
249 | mostrarResultado(passOrFail);
250 | let div = document.createElement("div");
251 | consoleArea.appendChild(div);
252 |
253 | consoleArea.lastElementChild.classList.add('current-line');
254 | consoleArea.lastElementChild.style.marginTop = "15px";
255 | lineaActual = document.querySelector('.current-line');
256 | lineaActual.innerHTML = '
';
257 |
258 | if (leccionActual > leccionesTotal) {
259 | // Mark navbar element as completed
260 | document.querySelector('.main-menu ul li:last-child a').classList.remove('learning');
261 | document.querySelector('.main-menu ul li:last-child a').classList.add('completed');
262 |
263 | setTimeout(function() {
264 | sweetAlert({
265 | title: "Congratulations!",
266 | text: config.tutorialCompletedMessage,
267 | html: true,
268 | type: "success",
269 | showConfirmButton: true
270 | });
271 | }, 5000);
272 | } else {
273 | actualizarInfoLeccion();
274 | // Ayudar listener para el textarea
275 | addTextareaListener();
276 | textarea.value = "";
277 | textarea.focus();
278 | }
279 | }, 1000);
280 |
281 | }
282 | // Add listener to text area every time it's appended in the console area
283 | function addTextareaListener() {
284 | textarea = document.querySelector('#console-input');
285 | textarea.addEventListener('keydown', (e) => {
286 |
287 | if (e.keyCode === 13) {
288 | e.preventDefault();
289 | if (textarea.value.trim().length < 1) {
290 | return;
291 | }
292 |
293 | if (textarea.value.trim() === 'clear') {
294 | consoleArea.appendChild(clearTerminal());
295 | addTextareaListener();
296 | textarea.focus();
297 | return;
298 | }
299 |
300 | if (textarea.value.trim() === 'clear') {
301 | consoleArea.appendChild(clearTerminal());
302 | addTextareaListener();
303 | textarea.focus();
304 | return;
305 | }
306 |
307 | if (textarea.value.trim() === lecciones[leccionActual].comando) {
308 | commandHist.push(textarea.value);
309 | cambiarLineaActual("pass");
310 | } else {
311 | commandHist.push(textarea.value);
312 | cambiarLineaActual();
313 | }
314 | }
315 |
316 | if (e.keyCode === 38 && commandPos <= commandHist.length && commandHist.length > 0) {
317 | // Up presses
318 | textarea.value = "";
319 | textarea.value = commandHist[commandHist.length - commandPos];
320 | commandPos++;
321 | }
322 | });
323 | }
324 | // Every time a lesson changes the navbar is rebuilt based on current lesson
325 | function createNavbarLinks() {
326 | let ul = document.createElement('ul');
327 | for (let i = 1; i <= leccionesTotal; i++) {
328 | let li = document.createElement('li');
329 | let a = createElementNode('a', lecciones[i].orden + " - " + lecciones[i].tituloCorto);
330 | li.appendChild(a).classList.add('nav-text');
331 | // Add link icon class
332 | if (i < leccionActual) {
333 | li.appendChild(a).classList.add('completed');
334 | } else {
335 | li.appendChild(a).classList.add('learning');
336 | }
337 | li.addEventListener('click', (e) => {
338 | if (navbar.classList.contains('expanded')) {
339 | e.stopPropagation();
340 | navbar.scrollTop = 0;
341 | consoleArea.appendChild(clearTerminal());
342 | addTextareaListener();
343 | leccionActual = i;
344 | avanceActual = (leccionActual - 1) * leccionPorcentaje;
345 | document.querySelector('#myBar').style.width = avanceActual + "%";
346 | actualizarInfoLeccion();
347 | // Actualizar Staged
348 | deleteAllChilds(repoStagedArea, 'h3');
349 | let leccionPrevia = leccionActual - 1 < 1 ? 1 : leccionActual - 1;
350 | if (lecciones[leccionPrevia].repoStatus.staged != undefined) {
351 | let folderStructure = createFolderStructure(lecciones[leccionPrevia].repoStatus.staged);
352 | repoStagedArea.appendChild(folderStructure);
353 | } else {
354 | let ul = document.createElement('ul');
355 | let li = createElementNode("li", config.emptyStageAreaMessage);
356 | ul.appendChild(li).classList.add('commit');
357 | repoStagedArea.appendChild(ul);
358 | }
359 | // Actualizar Repo Commits
360 | deleteAllChilds(repoCommitsArea, 'h3');
361 | if (lecciones[leccionPrevia].repoStatus.commits != undefined) {
362 | let ul = document.createElement('ul');
363 | for (let i = 0; i < lecciones[leccionPrevia].repoStatus.commits.length; i++) {
364 | let li = createElementNode("li", lecciones[leccionPrevia].repoStatus.commits[i]);
365 | ul.appendChild(li).classList.add('commit');
366 | }
367 | repoCommitsArea.appendChild(ul)
368 | } else {
369 | let ul = document.createElement('ul');
370 | let li = createElementNode("li", config.emptyCommitsAreaMessage);
371 | ul.appendChild(li).classList.add('commit');
372 | repoCommitsArea.appendChild(ul);
373 | }
374 | navbar.classList.remove('expanded');
375 | // Ayudar listener para el textarea
376 | textarea.value = "";
377 | textarea.focus();
378 | }
379 | })
380 | ul.appendChild(li);
381 | }
382 | return ul;
383 | }
384 | // creates a new textarea for the console
385 | // If added to the consoleArea it can efectively clear it,
386 | function clearTerminal() {
387 | deleteAllChilds(consoleArea);
388 | let div = document.createElement('div');
389 | div.classList.add('current-line');
390 | let img = document.createElement('img');
391 | img.setAttribute('src', './img/logo-blue.png');
392 | let newTextarea = document.createElement('textarea');
393 | div.appendChild(img).classList.add('line-marker');
394 | newTextarea.id = 'console-input';
395 | newTextarea.setAttribute('autocomplete', "off");
396 | newTextarea.setAttribute('autocorrect', "off");
397 | newTextarea.setAttribute('autocapitalize', "off");
398 | newTextarea.setAttribute('spellcheck', "false");
399 | div.appendChild(newTextarea);
400 | return div;
401 | }
402 |
403 | // =================================================
404 | // HELPER FUNCTIONS
405 | // ==================================================
406 | // Creates element tag with text
407 | function createElementNode(elementTagAsString, texto) {
408 | let element = document.createElement(elementTagAsString);
409 | element.innerHTML = texto;
410 | return element;
411 | }
412 | // Deletes every child elements but the one that matches the exception
413 | function deleteAllChilds(parentElement, exceptionTagAsString) {
414 | var target = 0;
415 | if (parentElement.childElementCount !== 0) {
416 | for (let i = 0; target < parentElement.childElementCount; i++) {
417 | if (exceptionTagAsString !== undefined &&
418 | parentElement.children[i].tagName === exceptionTagAsString.toUpperCase()) {
419 | target++;
420 | continue;
421 | }
422 | parentElement.removeChild(parentElement.children[target]);
423 | }
424 | }
425 | return;
426 | }
427 | // Return object length
428 | function getObjLength(obj) {
429 | let count = 0;
430 | let i;
431 |
432 | for (i in obj) {
433 | if (obj.hasOwnProperty(i)) {
434 | count++;
435 | }
436 | }
437 | return count;
438 | }
439 | // Creates the entire folder structure based on the folder array in JSON
440 | function createFolderStructure(folderArray) {
441 | let ul = document.createElement('ul');
442 | for (var i = 0; i < folderArray.length; i++) {
443 | var element = folderArray[i];
444 | if (typeof(element) === 'object') {
445 | for (var key in element) {
446 | let li = createElementNode('li', key);
447 | li.addEventListener('click', (e) => {
448 | e.target.nextSibling.classList.toggle('closed');
449 | })
450 | ul.appendChild(li).classList.add('folder');
451 | if (element[key].length > 0) {
452 | let liContainer = document.createElement('li');
453 | let innerUl = createFolderStructure(element[key]);
454 | liContainer.classList.add('closed');
455 | liContainer.appendChild(innerUl);
456 | ul.appendChild(liContainer);
457 | } else if (key === ".git") {
458 | let liContainer = document.createElement('li');
459 | liContainer.classList.add('closed');
460 | let innerUl = createElementNode('ul', 'Too many files to show! LOL');
461 | liContainer.appendChild(innerUl);
462 | ul.appendChild(liContainer);
463 | } else {
464 | let liContainer = document.createElement('li');
465 | liContainer.classList.add('closed');
466 | let innerUl = createElementNode('ul', 'Empty folder');
467 | liContainer.appendChild(innerUl);
468 | ul.appendChild(liContainer);
469 | }
470 | }
471 | } else {
472 | let li = createElementNode('li', element);
473 | ul.appendChild(li).classList.add('file');
474 | }
475 | }
476 |
477 | return ul;
478 | }
479 |
480 | // ===================================================
481 | // APLICATION FIRST START
482 | // ===================================================
483 |
484 | // Actualizar instrucciones al cargar
485 | actualizarInfoLeccion();
486 | // Ayudar listener para el textarea al cargar
487 | addTextareaListener();
488 | // Coloca nombre de Repo en header de folderArea
489 | document.querySelector('#repository .header .title').innerHTML = config.repoName;
490 | // Show body after one second
491 | setTimeout(function() {
492 | document.body.style.opacity = 1;
493 | }, 1000);
494 | // Click event for button that 'writes' commando in console
495 | document.querySelector('.comando').addEventListener('click', () => {
496 | textarea.value = "";
497 | textarea.classList.add("typed");
498 | textarea.value = lecciones[leccionActual].comando;
499 | setTimeout(function() {
500 | textarea.classList.remove("typed");
501 | textarea.focus();
502 | }, 1000);
503 | });
504 |
505 |
506 |
507 |
508 | // Mostrar y ocultar Menu principal
509 | navbar.addEventListener('click', (e) => {
510 | if (navbar.classList.contains('expanded') === false) {
511 | navbar.classList.toggle('expanded');
512 | }
513 | });
514 |
515 | document.querySelector('main').addEventListener('click', () => {
516 | navbar.classList.remove('expanded');
517 | navbar.scrollTop = 0;
518 | });
519 |
520 |
521 | // Mostrar y ocultar Sidebar menu
522 | document.querySelector('#showNavbar').addEventListener('mouseover', () => {
523 | setTimeout(function() {
524 | navbar.classList.add('expanded');
525 | }, 100);
526 | });
527 |
528 | document.querySelector('#showNavbar').addEventListener('mouseleave', () => {
529 | navbar.classList.remove('expanded');
530 | });
531 |
532 | // Mostrar y ccultar columna del repositorio
533 | document.querySelector('.hide-repo').addEventListener('click', () => {
534 | let column1 = document.querySelector('.column-1');
535 | let column2 = document.querySelector('.column-2');
536 | document.querySelector('.show-repo').classList.toggle('hidden');
537 | column1.style.width = '100%';
538 | column1.style.flexDirection = 'row';
539 | column2.classList.toggle('hidden');
540 |
541 | // Reordenar columna 1
542 | let instrucciones = document.querySelector('#instrucciones');
543 | let terminal = document.querySelector('#terminal');
544 | instrucciones.style.flex = '2';
545 | instrucciones.style.height = '100%';
546 | consoleArea.style.height = '100%';
547 | terminal.style.flex = '3';
548 | terminal.style.height = '100%';
549 | terminal.style.marginTop = '38.39px';
550 | })
551 |
552 | document.querySelector('.show-repo').addEventListener('click', () => {
553 | let column1 = document.querySelector('.column-1');
554 | let column2 = document.querySelector('.column-2');
555 | // Reordenar columna 1
556 | let instrucciones = document.querySelector('#instrucciones');
557 | let terminal = document.querySelector('#terminal');
558 | column1.style.width = '70%';
559 | column1.style.flexDirection = 'column';
560 | instrucciones.style.flex = '3';
561 | instrucciones.style.height = 'auto';
562 | terminal.style.flex = '2';
563 | terminal.style.marginTop = '0';
564 | setTimeout(function() {
565 | column2.classList.toggle('hidden');
566 | }, 900);
567 | document.querySelector('.show-repo').classList.toggle('hidden');
568 | })
569 | };
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | module.exports = {
4 | entry: './src/js/main.js',
5 | output: {
6 | filename: 'bundle.js',
7 | path: path.resolve(__dirname, 'public')
8 | },
9 | module: {
10 | rules: [
11 | {
12 | test: /\.js$/,
13 | include: [
14 | path.resolve(__dirname, 'js')
15 | ],
16 | exclude: /(node_modules|bower_components)/,
17 | use: {
18 | loader: 'babel-loader',
19 | options: {
20 | presets: ['babel-preset-es2015'],
21 | minimize: true
22 | }
23 | }
24 | }
25 | ]
26 | },
27 | devtool: 'source-map',
28 | devServer: {
29 | contentBase: './dist',
30 | disableHostCheck: true
31 | }
32 | };
--------------------------------------------------------------------------------